Last active
November 28, 2019 22:44
-
-
Save bebrws/f297bc4f0b695a8589fb4b12eacff829 to your computer and use it in GitHub Desktop.
sdfd
This file has been truncated, but you can view the full file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### Thisi s a big heaeder | |
A LIST | |
* sdf | |
* sfasdf | |
* j2 | |
* asd | |
* asdf | |
* kl | |
* k | |
## another header | |
```some code code goes here, a lot of good code. | |
for (let i = 0; i < 10; i ++) { | |
print(“Test message”) | |
} ``` | |
# a header | |
This is a list: | |
1. First item | |
2. Second item | |
3. Third item | |
This is more content | |
``` | |
spotlightEngine.swift | |
``` | |
``` | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
test | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
```### Thisi s a big heaeder | |
A LIST | |
* sdf | |
* sfasdf | |
* j2 | |
* asd | |
* asdf | |
* kl | |
* k | |
## another header | |
```some code code shere a lot of good code ``` | |
# a header | |
This is more content | |
``` | |
spotlightEngine.swift | |
``` | |
``` | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
test | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
```### Thisi s a big heaeder | |
A LIST | |
* sdf | |
* sfasdf | |
* j2 | |
* asd | |
* asdf | |
* kl | |
* k | |
## another header | |
```some code code shere a lot of good code ``` | |
# a header | |
This is more content | |
``` | |
spotlightEngine.swift | |
``` | |
``` | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
test | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
```### Thisi s a big heaeder | |
A LIST | |
* sdf | |
* sfasdf | |
* j2 | |
* asd | |
* asdf | |
* kl | |
* k | |
## another header | |
```some code code shere a lot of good code ``` | |
# a header | |
This is more content | |
``` | |
spotlightEngine.swift | |
``` | |
``` | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
test | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLog(@"BEBFL QUERY didnt start with bb:%@", query); | |
} | |
} | |
- (void)reloadResultsViews { | |
DLog(@"BEBFL reloadResultsViews in plugin engine"); | |
id appDelegate = [[NSApplication sharedApplication] delegate]; | |
@try { | |
DLog(@"BEBFL in reloadResultsViews"); | |
/* | |
SPResultViewController *resultVC = [appDelegate currentViewController]; | |
[resultVC setResults:resultVC.results]; | |
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_12) { | |
[resultVC reloadResultsSelectingTopResult:YES animate:NO]; | |
} else { | |
[[appDelegate mainViewController] reloadResultsSelectingTopResult:YES animate:NO]; | |
} | |
*/ | |
} @catch (NSException *exception) { | |
DLog(@"BEBFL Exception occured in relaod results: %@", exception); | |
} | |
[self updateWindowCollapsed]; | |
} | |
- (NSArray *)processSpotlightResults:(NSArray *)spotlightResults { | |
DLog(@"BEBFL processSpotlightResults in plugin engine"); | |
// for (id pluginHit in self.results) { | |
// | |
// } | |
// | |
// if ([self query] && [self query].length > 3) { | |
// | |
// /* | |
// for (id item in spotlightResults) { | |
// | |
// | |
// DLog(@"BEBFL one iteration of spotlightResults"); | |
// if ([item isKindOfClass:NSClassFromString(@"SomeClass")]) { | |
// // do nothing | |
// } else if ([item isGroupHeading]) { | |
// DLog(@"BEBFL item isGroupheading"); | |
// | |
// // This item could be on top? | |
// // Maybe check the displayName? | |
// if ([[item displayName] isEqualToString:@"ADisplayName"]) { | |
// } | |
// } | |
// } | |
// | |
// */ | |
// | |
// // Return the results unmodified | |
// return spotlightResults; | |
// } else { | |
// // DLog(@"BEBFL Query could still be a command so returnin an empty array for processing spotlight results"); | |
// // return [NSArray alloc]; | |
// return spotlightResults; | |
// } | |
DLog(@"BEBFL In process spotlight results before cmdOutput"); | |
if (self.cmdOutput != nil) { | |
DLog(@"BEBFL In process spotlight results and have cmdOutput, returning custom results"); | |
NSMutableArray *mainResults = [NSMutableArray new]; | |
//[mainResults addObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil]]; | |
id spResult = [[__SS_SPOpenAPIResultClass() alloc] initTextCell:@"TEST"]; | |
Class superclass = NSClassFromString(@"PRSResult"); | |
void (*superIMP)(id, SEL, NSString*, NSString*) = (void *)[superclass instanceMethodForSelector: @selector(initWithContentType:displayName:)]; | |
static NSInteger i = 0; | |
NSString *contentType = [NSString stringWithFormat:@"%li", i++]; // cycle the contentType to prevent the system from dropping new results that have an unchanged title | |
superIMP(spResult, _cmd, contentType, @"title"); // TODO: what does contentType actually do? it probably isn't a mime type | |
[spResult setTitle: @"title2"]; | |
//objc_setAssociatedObject(self, @selector(resultAssociatedObject), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | |
[mainResults addObject:spResult]; | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
[panel expand]; | |
// if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" focusString:nil] atIndex:0]; | |
// } else if ([NSClassFromString(@"SPGroupHeadingResult") instancesRespondToSelector:@selector(initWithDisplayName:keyID:focusString:)]) { | |
// [pluginNonTopHits insertObject:[[NSClassFromString(@"SPGroupHeadingResult") alloc] initWithDisplayName:@"FLASHLIGHT" keyID:nil focusString:nil] atIndex:0]; | |
// } else { | |
// NSLog(@"SPGroupHeadingResult header seems to have changed ☠️"); | |
// } | |
// [mainResults insertObjects:pluginNonTopHits atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, pluginNonTopHits.count)]]; | |
return mainResults; | |
} | |
return spotlightResults; | |
} | |
- (void)updateWindowCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// if ([self shouldBeCollapsed] != [panel isCollapsed]) { | |
// if ([self shouldBeCollapsed]) { | |
// [panel collapse]; | |
// } else { | |
// [panel expand]; | |
// } | |
// } | |
} | |
- (BOOL)shouldBeCollapsed { | |
DLog(@"BEBFL updateWindowCollapsed"); | |
// SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
// SPSearchPanel *panel = delegate.window; | |
// | |
// BOOL queryEmpty = self.query.length == 0; | |
// BOOL queryFinished = self.query == self.mostRecentQueryWithResults || [self.query isEqualToString:self.mostRecentQueryWithResults]; | |
// BOOL noResults = self.results.count == 0; | |
// BOOL isCollapsedNow = [panel isCollapsed]; | |
// | |
// BOOL canCollapse = queryEmpty || (queryFinished && noResults) || (!queryFinished && noResults && isCollapsedNow); | |
// | |
// return self.spotlightWantsCollapsed && canCollapse; | |
return true; | |
} | |
@end | |
Class __SS_SPOpenAPIResultClass() { | |
Class c = NSClassFromString(@"SPOpenAPIResult"); | |
if (c) return c; | |
c = objc_allocateClassPair(ZKClass(PRSResult), [@"SPOpenAPIResult" UTF8String], 0); | |
objc_registerClassPair(c); | |
ZKSwizzle(_SPOpenAPIResult, SPOpenAPIResult); | |
return c; | |
} | |
```### Thisi s a big heaeder | |
A LIST | |
* sdf | |
* sfasdf | |
* j2 | |
* asd | |
* asdf | |
* kl | |
* k | |
## another header | |
```some code code shere a lot of good code ``` | |
# a header | |
This is more content | |
``` | |
spotlightEngine.swift | |
``` | |
``` | |
// | |
// _SPPlusPluginEngine.m | |
// SPPlusSIMBL | |
// | |
// | |
// | |
// | |
#define DLog(fmt, ...) NSLog((@"BEBFL Spotlight %s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); | |
#define DWWIDTH 500 | |
#define DWHEIGHT 200 | |
#define DWTOPOFFSET 100 | |
#import "ZKSwizzle.h" | |
#import "_SPPlusPluginEngine.h" | |
#import <AppKit/AppKit.h> | |
#import "SPResultViewController.h" | |
#import "SPResult.h" | |
#import "SPGroupHeadingResult.h" | |
#import "SPSearchPanel.h" | |
#import "SPAppDelegate.h" | |
#import "SPMainViewController.h" | |
#import <objc/runtime.h> | |
#import "SKShell.h" | |
Class __SS_SPOpenAPIResultClass(void); | |
@interface cleanHUD : NSObject | |
@end | |
@interface NOCNSWindow : NSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen; | |
@end | |
@implementation NOCNSWindow | |
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen { | |
return frameRect; | |
} | |
-(void)viewDidAppear:(BOOL)animated{ | |
NSLog(@"viewDidAppear is running"); | |
//[super viewDidAppear: animated]; | |
[NSApp activateIgnoringOtherApps:true]; | |
} | |
- (void)setWinPost:(float)x toY:(float)y { | |
DLog(@"setWinPost Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:x] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:y] stringValue]); | |
} | |
- (void)setWinPosByScreen { | |
CGRect scr = [NSScreen mainScreen].visibleFrame; | |
float xPos = scr.origin.x + (scr.size.width / 2) - 117; | |
float yPos = scr.origin.y + scr.size.height + 1; | |
// Adjust for fullscreen | |
if (yPos == [NSScreen mainScreen].frame.size.height || yPos == [NSScreen mainScreen].frame.size.height + [NSScreen mainScreen].frame.origin.y) | |
yPos -= 22; | |
DLog(@"setWinPosByScreen Setting the window position to:"); | |
DLog(@"x:%@", [[NSNumber numberWithFloat:xPos] stringValue]); | |
DLog(@"y:%@", [[NSNumber numberWithFloat:yPos] stringValue]); | |
// Set origin | |
CGPoint frmLoc = CGPointMake(xPos, yPos); | |
[self setFrameOrigin:frmLoc]; | |
} | |
@end | |
// BEB TODO Maybe move to Plgun negine porperty? | |
@interface _SPPlusPluginEngine () | |
@property (nonatomic) NSArray *results; | |
@property (nonatomic) NSString *mostRecentQueryWithResults; | |
@property (nonatomic) SPAppDelegate *delegate; | |
@property (nonatomic) NOCNSWindow* myModalWindow; | |
@property (nonatomic) NSTextField * mLabel; | |
@property (nonatomic) NSModalSession session; | |
@property (nonatomic) Boolean isModalShown; | |
@property (nonatomic) NSView *myView; | |
// @property (nonatomic) NSMutableString *lastQuery; | |
@property (nonatomic) NOCNSWindow *dbgWin; | |
@property (nonatomic) NSTextField *dLabel; | |
@property (nonatomic) NSString *cmdOutput; | |
@end | |
@implementation _SPPlusPluginEngine | |
+ (_SPPlusPluginEngine *)shared { | |
static _SPPlusPluginEngine *shared = nil; | |
static dispatch_once_t onceToken; | |
dispatch_once(&onceToken, ^{ | |
DLog(@"BEBFL creating new plugin engine"); | |
shared = [_SPPlusPluginEngine new]; | |
}); | |
return shared; | |
} | |
- (id)init { | |
self = [super init]; | |
DLog(@"BEBFL in plugin engine"); | |
self.cmdOutput = nil; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
NSApplication *app = [NSApplication sharedApplication]; | |
DLog(@"Just starting to create the window frames"); | |
NSRect sFrame = [[NSScreen mainScreen] visibleFrame]; | |
NSRect windowRectForFullScreenAll = NSMakeRect(0, sFrame.size.height, sFrame.size.width, sFrame.size.height); | |
NSRect screenFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-100, sFrame.size.height-100); | |
DLog(@"Just starting to create the modal window for debug output"); | |
self.dbgWin = [[NOCNSWindow alloc] initWithContentRect:screenFrame //NSMakeRect(sFrame.origin.x + (sFrame.size.width / 2) - DWWIDTH/2, sFrame.origin.y + sFrame.size.height, DWWIDTH, DWTOPOFFSET) | |
styleMask:0 | |
backing:NSBackingStoreBuffered | |
defer:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 2]; | |
// [dbgWin setLevel:NSMainMenuWindowLevel + 99999]; | |
[self.dbgWin setMovableByWindowBackground:NO]; | |
[self.dbgWin makeKeyAndOrderFront:nil]; | |
[self.dbgWin setIgnoresMouseEvents:YES]; | |
//[self.dbgWin setOpaque:false]; | |
[self.dbgWin setBackgroundColor:[NSColor clearColor]]; | |
[self.dbgWin.contentView setWantsLayer:true]; | |
// Round conrners | |
[self.dbgWin.contentView.layer setCornerRadius:4]; | |
// Show it irhgt off for debugging | |
//[self.dbgWin setAlphaValue:0.5]; | |
// Hide HUD | |
//[dbgWin setAlphaValue:1.0]; | |
// Add views to the dbgWin | |
//[self.myModalWindow setAlphaValue:0.5]; | |
self.dLabel = [[NSTextField alloc] initWithFrame: self.dbgWin.frame]; // screenFrame];//[self myModalWindow].frame]; | |
self.dLabel.stringValue = @"THIS IS THE DEBYG VIEW"; | |
self.dLabel.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[self.dLabel setTextColor:[NSColor systemRedColor]]; | |
self.dLabel.drawsBackground = false; | |
self.dLabel.editable = false; | |
self.dLabel.bezeled = false; | |
self.dLabel.selectable = true; | |
[self.dbgWin.contentView addSubview:self.dLabel]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
self.myView = [[NSView alloc] initWithFrame:self.dbgWin.frame]; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
CGPoint frmLoc = CGPointMake(0, 0); | |
[self.dbgWin setFrameOrigin:frmLoc]; | |
[self.dbgWin setLevel:NSMainMenuWindowLevel + 999]; | |
[self.dbgWin setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
[NSApp runModalForWindow: self.dbgWin]; | |
//self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
}); | |
//SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
//SPSearchPanel *panel = delegate.window; | |
DLog(@"Just starting to create the modal window for output"); | |
//NSRect screenFrame = [NSScreen mainScreen].frame; | |
self.myModalWindow = [[[NOCNSWindow alloc] initWithContentRect:screenFrame | |
styleMask:NSBorderlessWindowMask | |
backing:NSBackingStoreBuffered | |
defer:NO] init]; | |
// [[self myModalWindow] setBackgroundColor:[NSColor orangeColor]]; | |
// BEB TODO ENABLE ALPHA | |
//[self.myModalWindow setAlphaValue:0.5]; | |
NSRect labelFrame = NSMakeRect(100 , 100, | |
sFrame.size.width-200, sFrame.size.height-200); | |
self.mLabel = [[NSTextField alloc] initWithFrame:labelFrame]; // screenFrame];//[self myModalWindow].frame]; | |
[self mLabel].stringValue = @"THIS IS WHERE CONTENTGOES"; | |
[self mLabel].font = [NSFont fontWithName:@"Menlo" size:14]; | |
[[self mLabel] setTextColor:[NSColor systemRedColor]]; | |
[self mLabel].backgroundColor = [NSColor systemRedColor]; | |
[self mLabel].drawsBackground = false; | |
[self mLabel].editable = false; | |
[self mLabel].bezeled = false; | |
[self mLabel].selectable = true; | |
[[self myModalWindow].contentView addSubview:[self mLabel]]; | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
DLog(@"BEBFL The modalWindow has been created and a NSTextField has been added"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
}); | |
DLog(@"BEBFL Created window for results."); | |
self.delegate = (id)[[NSApplication sharedApplication] delegate]; | |
return self; | |
} | |
- (void)setQuery:(NSString *)query { | |
// Note self here is a SPAppDelegate | |
// This is called frmoa swizzled function overriding | |
// setQuery: id(SPQuery)query | |
// with arguments like that the name of the message changes to | |
// sendQueryid | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
// or | |
// panel.mainView.frame | |
NSTextField *none = [[NSTextField alloc] initWithFrame: panel.frame]; // screenFrame];//[self myModalWindow].frame]; | |
none.stringValue = @"THIS IS WHERE CONTENTGOES"; | |
none.font = [NSFont fontWithName:@"Menlo" size:14]; | |
[none setTextColor:[NSColor systemRedColor]]; | |
none.backgroundColor = [NSColor systemRedColor]; | |
none.drawsBackground = false; | |
none.editable = false; | |
none.bezeled = false; | |
none.selectable = true; | |
[panel.mainView addSubview: none]; | |
DLog(@"BEBFL in Set a new query:%@.", query); | |
_query = query; | |
if (!query) { //if (query == nil || !query) { // || query == NSNull) { | |
DLog(@"BEBFL The query is nil"); | |
} else { | |
NSString *queryLength = [[NSString alloc] initWithFormat:@"%d", query.length]; | |
DLog(@"BEBFL query count:%@.", queryLength); | |
NSString *startingString = @"bb "; | |
NSString *finalString = @";"; | |
NSString *clearQuery=@"c;"; | |
NSString *restartSpotlight = @"rs;"; | |
// if ([_query hasPrefix: clearQuery]) { | |
if (query && [query hasPrefix: restartSpotlight]) { | |
DLog(@"BEBFL Got the restart Spotlight command"); | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
[ [ SKShell currentShell ] runCommand: @"sudo pkill Spotlight" | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog(@"BEBFL Clearing Spotlight command has run!"); | |
}]; | |
}); | |
} else if (query && [query hasPrefix: clearQuery]) { | |
DLog(@"BEBFL Got the Cancel command fro a modal!"); | |
self.cmdOutput = nil; | |
[self dLabel].stringValue = @""; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Clearing Spotlight query from main thread after a clear modal command."); | |
[self.delegate resetQuery]; | |
}); | |
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL Delay returned"); | |
// Will hide the modal when they open Spotlight again and type c; | |
DLog(@"BEBFL Hiding the NSApp modal"); | |
if (self.isModalShown) { | |
DLog(@"BEBFL The boolean says the modal is shown so I am stopping it"); | |
// [NSApp stopModal]; | |
[NSApp endModalSession:[self session]]; | |
self.isModalShown = false; | |
} else { | |
DLog(@"BEBFL NSApp Sheet is attempting to hdie the modal but its not marked as shown."); | |
} | |
// [NSApp endModalSession:[self session]]; | |
// if ([NSApp isHidden]) { | |
// DLog(@"BEBFL App is hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// //[self myModalWindow].isVisible = false; | |
// // [[self myModalWindow] close]; | |
// | |
// //[[self myModalWindow] orderOut:self]; | |
// } else { | |
// DLog(@"BEBFL App is not hidden, hiding the NSApp modal"); | |
// [NSApp endModalSession:[self session]]; | |
// // MUST remember to give back memory AND close the window BEFORE | |
// // stopModel or else the UIView window will be frozen | |
// // | |
// // [[self myModalWindow] orderOut:nil]; // Clean up memory after showing the window | |
// //[self myModalWindow].isVisible = false; | |
// //[[self myModalWindow] close]; | |
// | |
// [NSApp stopModal]; | |
// | |
// } | |
//}); | |
} else if (query && [query hasPrefix: startingString] && [query hasSuffix:finalString]) { | |
// if ([_query hasPrefix: startingString] && [_query hasSuffix:finalString]) { | |
//[self.lastQuery setString:query]; | |
DLog(@"BEBFL WE GOT A FINISHED BB QUERY!!!????!"); | |
// [self setQuery:@""]; | |
// [self resetQuery]; | |
NSRange endRange = [query rangeOfString: finalString options: NSBackwardsSearch]; | |
NSString* parsed = [query substringToIndex: endRange.location]; | |
parsed = [parsed substringFromIndex: [startingString length]]; | |
DLog(@"BEBFL WE GOT A PARSED QUERY:%@", parsed); | |
// | |
// NSArray *cmdArray = [parsed componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; | |
// NSMutableArray* mutableArray = [cmdArray mutableCopy]; | |
// NSString *firstCmd = mutableArray[0]; | |
// [mutableArray removeObjectAtIndex:0]; | |
// NSArray *restOfArray = [mutableArray copy]; | |
DLog(@"BEBFL A Newword before the shell command"); | |
// | |
@try { | |
[ [ SKShell currentShell ] runCommand: parsed | |
completion: ^( int status, NSString * output, NSString * error ) | |
{ | |
DLog( @"BEBFL Command status %i", status ); | |
DLog( @"BEBFL Command output %@", output ); | |
DLog( @"BEBFL Command error %@", error ); | |
// if (!error) { | |
// self.cmdOutput = output; | |
// } | |
self.cmdOutput = output; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
DLog(@"BEBFL NSApp Sheet is attempting to update and be shown."); | |
if (!self.isModalShown) { | |
self.isModalShown = true; | |
DLog(@"BEBFL Got an attempt to show the modal AND ITS MARKED AS NOT SHOWN!"); | |
// self.session = [NSApp beginModalSessionForWindow:[self myModalWindow]]; | |
//[[self myModalWindow] setLevel:NSMainMenuWindowLevel + 999]; | |
//[[self myModalWindow] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; | |
//[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
//[[self myModalWindow] setLevel:NSStatusWindowLevel]; | |
[self mLabel].stringValue = output; | |
[self dLabel].stringValue = output; | |
self.session = [NSApp beginModalSessionForWindow:[self dbgWin]]; | |
/* | |
if ([NSApp runModalSession:[self session]] != NSRunContinuesResponse) { | |
DLog(@"BEBFL NSApp Sheet is being shown in if!"); | |
} | |
[[self myModalWindow] makeKeyAndOrderFront:nil]; | |
[[self myModalWindow] setLevel:NSPopUpMenuWindowLevel]; | |
[NSApp activateIgnoringOtherApps: true]; | |
*/ | |
SPAppDelegate *delegate = (id)[[NSApplication sharedApplication] delegate]; | |
SPSearchPanel *panel = delegate.window; | |
NSApplication *app = [NSApplication sharedApplication]; | |
// | |
// NSAlert *alert = [[NSAlert alloc] init]; | |
// [alert addButtonWithTitle:@"Continue"]; | |
// [alert setMessageText:@"Output"]; | |
// [alert setInformativeText:output]; | |
// [alert setAlertStyle:NSWarningAlertStyle]; | |
// [alert beginSheetModalForWindow:panel modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; | |
// [app mainWindow] | |
// [[self myModalWindow].contentView addSubview:[self mLabel]]; | |
DLog(@"BEBFL NSApp Sheet is being shown!"); | |
} else { | |
DLog(@"BEBFL Got an attempt to show the modal when it is already marked as shown"); | |
DLog(@"BEBFL Just gonna update text"); | |
[self mLabel].stringValue = output; | |
} | |
}); | |
} | |
]; | |
} @catch (NSException *exception) { | |
DLog (@"BEBFL Command failed in exception: %@", exception); | |
} | |
// dispatch_async(dispatch_get_main_queue(), ^{ | |
// DLog(@"BEBFL Clearing Spotlight query from main thread"); | |
// [self.delegate resetQuery]; | |
// }); | |
DLog(@"BEBFL EMPTY"); | |
//SPResultViewController *resultVC = [appDelegate currentViewController]; | |
//[resultVC setResults: []] | |
return; | |
} | |
DLo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment