Global shortcut work but system play Error sound - macos

I create global shortcut with this code:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent * theEvent) {
int modiferKeys = NSControlKeyMask | NSAlternateKeyMask;
if (([theEvent keyCode] == 7 && modiferKeys)) {
NSLog (#"%#",#"work");
}
}];
}
This code work perfect, but when some application have a focus (for example Xcode, AppStore...) the system play Error sound.
How fix it?
Thaks.

A different way to implement a global hot key is using RegisterEventHotKey, declared in CarbonEvents.h. The docs for it might be under "legacy", but as far as I can tell from the header, it's not deprecated and is available in 64-bit code.

Related

How get an item in control center of Touch Bar on the right?

The app TouchSwitcher add item beside lightscreen and volume items :
https://hazeover.com/touchswitcher.html
Is there a solution to display an item into the control strip on the right region of touch bar ?
I can't find any help in official documentation about it...
Please help me !
After decompiling, I discovered some APIs in a framework called DFRFoundation located under /System/Library/PrivateFrameworks, and a related method DFRElementSetControlStripPresenceForIdentifier. I find it quite difficult to get further, so I answer here only to let you know that the API for this is in a private framework. Hope someone would reveal the secrets someday.
Here's what I use. Pass an NSView and an identifier of your choice to the controlStrippify() function. My attempts at doing the exact same thing using Swift have resulted in crashes, ports welcome :). Inspiration from https://github.com/a2/touch-baer.
#import Cocoa;
#import Foundation;
// See: https://github.com/a2/touch-baer
extern void DFRElementSetControlStripPresenceForIdentifier(NSString *string, BOOL enabled);
#interface NSTouchBarItem ()
+ (void)addSystemTrayItem:(NSTouchBarItem *)item;
#end
#interface NSTouchBar ()
+ (void)presentSystemModalFunctionBar:(NSTouchBar *)touchBar systemTrayItemIdentifier:(NSString *)identifier;
#end
void controlStrippify(NSView *view, NSString *identifier) {
if (#available(macOS 10.12.2, *)) {
NSCustomTouchBarItem *touchBarItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
touchBarItem.view = view;
[NSTouchBarItem addSystemTrayItem:touchBarItem];
DFRElementSetControlStripPresenceForIdentifier(identifier, YES);
} else {
// Fail!
}
}

UIDocumentInteractionController - MailCompose not dismissing in iOS8

I have a very strange (& serious) problem.
My app uses a UIDocumentInteractionController to share a PDF document.
When the user selects the "Mail" option in the controller's pop-up the MailCompose window is opened.
But, neither the Send nor Cancel button in this window causes the MailCompose window to be dismissed, meaning the user gets stuck and has to kill the app. The mail does go out though.
Here's the catch:
This happens only in iOS8 (both versions released so far) and only on apps installed via the AppStore. That EXACT same version of the app, when running on my device via USB debugging works fine.
Here's some code:
-(void)sharePDF:(id)sender
{
#try
{
NSURL *fileURL = [NSURL fileURLWithPath:currentFileObject.LocalPath];
if(fileURL)
{
//UIDocumentInteractionController
NSString *newPath;
#try
{
//Create a copy of the file for sharing with a friendly name
if (currentFileObject.isSpecialReport)
{
newPath = [svc saveReport:[NSData dataWithContentsOfURL:fileURL] ToFile:[NSString stringWithFormat:#"%#.pdf", currentFileObject.ReportName]];
}
else
{
newPath = [svc saveReport:[NSData dataWithContentsOfURL:fileURL] ToFile:[NSString stringWithFormat:#"%#.pdf", currentFileObject.PatientFullName]];
}
}
#catch (NSException *exception) {
return;
}
NSURL *newURL = [NSURL fileURLWithPath:newPath];
self.docController = [UIDocumentInteractionController interactionControllerWithURL:newURL];
self.docController.delegate = self;
if (currentFileObject.isSpecialReport)
{
self.docController.name = [NSString stringWithFormat:#"Pathology - %#", currentFileObject.ReportName];
}
else
{
self.docController.name = [NSString stringWithFormat:#"Pathology - %#", currentFileObject.PatientFullName];
}
[self.docController presentOptionsMenuFromBarButtonItem:btnShare animated:YES];
}
}
#catch (NSException *exception) {
return;
}
}
I do not implement any of the delegate methods since non of them are required, I also do not make use of the preview functionality.
What's most puzzling to me is that the app from the AppStore behaves differently than my local one although the code is identical. My next step is to use the new beta developer tools (Test Flight) to re-publish the app, hoping that I can replicate the problem.
EDIT: I found a similar question on SO here: Cannot dismiss email sheet invoked from UIDocumentInteractionController in iOS 8
After reading that post I think it worth mentioning that I submitted the app to the AppStore via XCode 5 (the last version before XCode 6). Can that really be a factor here? Does Apple not use the same version on their side as the version in which the app was originally built?
I think this is a bug in iOS 8, and if it's still not working for you, I don't think Apple are likely to fix it. I'd upgrade to Xcode 6 and see if that fixes it for you. (It did for us, as you've discovered).

Need to get the list of currently running applications visible to the user on MAC

I am developing in MAC and need to get the list of all the active applications currently running, I mean the ones which have actual window and the user can see/close/minimize/maximize.
I tried using NSWorkspace runningApplications function, but it gives a long list of applications (most probably it also lists some hidden applications) but I need only the ones that has window UI.
I've also used the suggestion in the following post to get the windows below the Dock and it worked fine in case if the Dock is visible:
CGWindowListCreate generates a hugely long list of windows
However when the Dock is hidden this solution doesn't work.
Does anyone have any idea how to get the list of running applications visible to user on MAC?
It may help you. Try this
for (NSRunningApplication *app in [[NSWorkspace sharedWorkspace] runningApplications]) {
NSLog(#"%#",[app localizedName]);
}
#import <Foundation/Foundation.h>
void ListWindows()
{
NSMutableArray* windows =
(__bridge NSMutableArray *)CGWindowListCopyWindowInfo(
kCGWindowListOptionOnScreenOnly |
kCGWindowListExcludeDesktopElements,
kCGNullWindowID);
for (NSDictionary* window in windows) {
if([[window objectForKey:#"kCGWindowLayer" ] intValue] == 0)
{
NSLog(#"%#", [window objectForKey:#"kCGWindowOwnerName"]);
}
}
}
int main(int argc, const char * argv[])
{
NSLog(#"Active windows:");
ListWindows();
return 0;
}
Sample output :
Active windows:
Xcode
TextEdit
Finder

Command line tool with user interface

I created a command line tool. I have my project almost done, but now I need to create an user interface to ask for user credentials.
Is possible to add a window to my command line project, or I have to create a cocoa application to do that?
A command-line tool won't have a connection to the window server (that's done by NSApplication), so no, it can't create a window. If you need to show a window for any reason, it probably should be an application at that point anyway, so you should go with that and make it one.
A Cocoa App would work. I haven't used Tcl/Tk or MacRuby, but if you're brand new to Cocoa you might have an easier time picking them up.
You can't do this in AppleScript without using AppKit APIs; see Prompt user for password with dialog window when using sudo.
If you're really asking an Xcode question, you might want to repost something more specific, likeĀ "how do I convert my Command-Line project so I can add a Cocoa window."
Yea Peter is right, you should make it into an application but that doesn't mean you need to convert the tool into a Cocoa app, you can keep a command line tool alive with a UI by utilising the NSApplication class but not using NSApplicationMain() to launch it. In your situation however I don't think this is the necessary method but anyway here is how I displayed a window in a command line tool:
#interface CustomAppClass : NSApplication
#property (strong) NSWindow *theWindow;
#end
#implementation CustomAppClass {
BOOL terminate;
}
- (void)finishLaunching {
/* Draw windows and stuff */
self.theWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 300, 200) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:NO];
[self.theWindow setTitle:#"Why Hello There!"];
[self.theWindow center];
[self.theWindow makeKeyAndOrderFront:self.theWindow];
}
// Override run and terminate: methods
- (void)run {
terminate = NO;
[self finishLaunching];
do {
NSEvent *event = [self nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES];
[self sendEvent:event];
[self updateWindows];
} while (!terminate);
}
- (void)terminate:(id)sender {
terminate = YES;
}
#end
int main(int argc, const char * argv[]) {
// Do all your pre functions here
/* Make NSApplication from CustomAppClass */
CustomAppClass *appObject = [CustomAppClass sharedApplication];
if ([appObject respondsToSelector:#selector(run)]) {
[appObject performSelectorOnMainThread:#selector(run) withObject:nil waitUntilDone:YES];
}
// Do all your post functions here.
return 0;
}
Sorry I didn't describe how to ask for credentials and stuff but if you want an official window based authentication (not sudo) you should probably look into the Security framework.
Some Credit to https://www.cocoawithlove.com/2009/01/demystifying-nsapplication-by.html
Hope this helps in any way.

Cocoa: Plugin Cannot Open App Window

I am developing an plugin for OsiriX.
In that app i have 3-4 nib files. Also in for plugin there are files (.h & .m) called PluginFilter where method called - (long) filterImage:(NSString) menuName is present from which the plugin start execution. Now my problem is that, I have return the code to launch main window is in some other .m file and I have to call that file using the method mentioned above.
The app has multiple nib files. I have a plugin name PluginFilter called by:
- (long) filterImage:(NSString*) menuName
The plugin should open a window when called by this method. The code that defines the window controller is in another nib. When I call the filterimage method in the plugin, the window never appears.
Here is my filterImage: method.
#import "XGridInOsiriXFilter.h"
#import "MainWindowController.h"
#implementation XGridInOsiriXFilter
- (void) initPlugin
{
}
- (long) filterImage:(NSString*) menuName
{
MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init];
[mainWindowController showWindow:self ];
[mainWindowController release];
return 0;
}
#end
Calling the method produces not warnings or errors, the window simply fails to appear.
I recognize this may be coming a little too late but I was looking for a way to do the same thing you are asking for and found it. You can use NSBundle to load the desired nib and point it to an instantiated controller. Like:
#implementation YourPluginFilter
- (void) initPlugin
{
yourWindowController = [[YourWindowController alloc] init];
NSLog(#"Initialized YourWindowController");
}
- (long) filterImage:(NSString*) menuName
{
if (yourWindowController && [NSBundle loadNibNamed:#"YourNibName" owner:yourWindowController]) {
NSLog(#"Activated yourWindowController");
return 0;
} else {
return -1;
}
}
#end
You would normally not open the app's main window from a plugin. Plugins by definition my not always be present so you should not put critical code in them. Neither would you want multiple plugins opening the same logical window.
Instead, the main window should be displayed by the app delegate as normal but the content of the window can be processed by a plugin if the plugin is available.
The main application should load and configure the main window and only call the plugin to process the contents of the window.
Even so it is technically possible to open a window from a plugin so either (1) the plugin is not being loaded and the method is not being called (insert breakpoint/log to confirm) or (2) the window controller is misconfigured so that it does not open the window. Test the controller outside the plugin to confirm it works. Better yet, move the window opening code outside the plugin.
Edit01:
From comment:
I have made some changes in the above
code as follows
- (long) filterImage:(NSString*) menuName {
MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];
[mainWindowController showWindow:self ];
[mainWindowController release];
return 0;
}
but it is showing wanring that no
-init method found. Why it is showing like this because -init method is der
in the MainWindowController.m file
Well, you have two problems here.
(1) You set define mainWindowController as of class MainWindowController but you initialize it with class GridSampleMainWindowController. If MainWindowController is a subclass of GridSampleMainWindowController this will work but will generate warnings. You should instead initialize it like
GridSampleMainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];
or
MainWindowController *mainWindowController = [[MainWindowController alloc] init:self];
(2) You release the controller without any other object retaining it which will kill it. When a window controller dies it deallocates the windows it controls. This is most likely why you see nothing.
You should sort out what class you want the controller to be and then set it as a retained property of the plugin class so you can keep it an its window around.
Which init method is it complaining about? Your initPlugin does nothing and returns a void if that is the plugin's actual initialization method then the plugin will never load. It should at least look like this:
- (id) initPlugin
{
self=[super init];
return self;
}
It looks like you come from a pure C background which is great for this environment but you need to learn about the object oriented parts of the Objective-C language. You're still writing methods as if they were old school C functions and there are important and oft times subtle differences.
Sorry I missed all this yesterday. I saw "plugin" and focused on the wrong aspect of the problem.
Edit02:
No i m not talking about my initPlugin
method. I am talking about my init
method which is there in
MainWindowController.m file
- (id)init {
self = [super initWithWindowNibName:#"MainWindow"];
return self;
}
This will return an instance of the MainWindowController's super class. If you're not doing any customization you have no need to override the init method in you subclass. Just use the inherited version thusly:
MainWindowController *mainWindowController = [[MainWindowController alloc] initWithWindowNibName:#"MainWindow"];

Resources