Dock "Turn Hiding On" programmatically from within an app - swift

If you secondary-click on the Dock you can click the Turn Hiding On option to automatically hide the Dock. Alternatively, you can go to System Preferences > Dock and click the Automatically hide and show the Dock.
I want to mimic that functionality from within an app I am making (which is basically a status bar icon app) and preferably in Swift.
The code I have written so far to turn on the Dock Automatic Hiding functionality is the following:
// Update the value for key "autohide" in com.apple.dock.plist, located in ~/Library/Preferences/.
var dict = NSUserDefaults.standardUserDefaults().persistentDomainForName("com.apple.dock")
dict.updateValue(true, forKey: "autohide")
NSUserDefaults.standardUserDefaults().setPersistentDomain(dict, forName: "com.apple.dock")
// Send notification to the OS.
dispatch_async(dispatch_get_main_queue()) {
CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(), "com.apple.dock.prefchanged", nil, nil, true)
}
The first part of the code updates a value in a plist file and I have confirmed that that is working. The second part sends a notification to the OS to tell it that a value has been changed in that plist, which I have also confirmed to be working.
However, these two things are not making the Dock hide, making me believe I need to do something else. Or made my approach to the problem is wrong? How do I make the Dock start hiding?
PS: I have read something about a private, undocumented API called CoreDock, but I would like to avoid going that way, as it may cause many problems...

Almost certainly better to use AppleScript or the Scripting Bridge to do this. The following script turns Dock autohiding on:
tell application "System Events"
set autohide of dock preferences to true
end tell
You can run that using NSAppleScript.

Related

Add to Accessibility

Alright, my app uses features which require Accessibility, and so I have to bring up the System preferences menu so the user can add our app.
First, I check if Accessibility is enabled. I can do that easily, but I'm having trouble bringing up the systems pane with the Application added to the side panel.
First, I tried using a dictionary along with AXIsProcessTrusted, but to no avail; no dialog showed.
Second, I tried using a trick:
let event = CGEvent(keyboardEventSource: nil, virtualKey: 0, keyDown: true)
event.post(.cghidEventTap)
If our app is not added to Accessibility, then a dialog will pop up, and everything that goes along with it.
Now the important part is that when you press Deny on the dialog, it will still add our app to the Accessibility, but it will NOT be checked.
The issue is that when you do the trick again, and the app is added to Accessibility but is NOT checked, then nothing will happen. No indicators, nothing. That means you don't know if it showed up or not.
Now the third thing i tried is using
NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility")!)
, which brings up the Accessibility menu.
However, it does not add our app to the side panel.
I've also tried using https://stackoverflow.com/a/18121292/14834900, however, all that does is just bring up the menu, like #3.
Recap
The first method does not work.
The second method brings up the dialog only when our app is not present in Accessibility, but gives no indicator of whether it brought the dialog up or not, which is required because if it did not bring up the dialog, then I would just use method #3, else, I would just continue.
The third method works but does not add our app to the side panel, so the user has to do it himself.
Is there anyway to make the third method add our app to Accessibility, but with it not checked, just like method #2?
The biggest issue I'm facing right now is how to add our app to the Accessbility side panel programmatically, just like the Trick #2
Thanks, I really appreciate it if anybody can lend a hand.

How to close System dialogs that appears on app crash?

I'm using xcuitest framework to automate mac application. I get system dialogs when the app is opened again after it crashes. I want to handle the dialog programmatically. But the dialog appears under the process `UserNotificationCenter' instead of the application under test. How can I handle the alert in such case?
You have two options:
Use InterruptionMonitor (documentation, use-case). This
approach is however kinda old and I found, that it does not work for
all dialogs and situations.
Create a method, which will wait for some regular app's button. If the app's button (or tab bar or other such XCUIElement) is visible and hittable after your app started, you can proceed with your test and if it's not, you can wait for the UserNotificationCenter dialog's button and identify&tap it by its string/position.
I'm using the second approach and its working much better, than the InterruptionMonitor. But it really depends on your app layout and use-case.
You should be able to revent it from appearing in the first place. Something like:
defaults write com.apple.CrashReporter DialogType none

Is it possible to write a custom TouchBar app for an existing application?

I have tried looking for an answer to this but can't seem to see anything about it.
I have a piece of software on my laptop (not written by me), that I want to customise. Some of the tasks I do are very repetitive, and could be simplified by just pressing a button on the Touch Bar that executes a number of commands.
Is it possible to write a Touch Bar app that either:
1) Customises the application's original TouchBar app (for which there is none)
2) Runs only when that application is running, and hides when the application is out of focus
Thanks
I believe BetterTouchTool can do that.
Also in the "App Specific" button you can customise when to hide system touch bar and when to show it again

How can I make an OS X application unfocusable while still receiving click events?

I'm developing an on screen keyboard application for OS X, similar to the one that's built in to the operating system (Keyboard Viewer). I seem to have hit a wall as I'm not sure how I can accept click events from buttons and not steal focus from the currently activated application. I know this is possible since there are apps that already do this, e.g. AssistiveWere's KeyStrokes.
So my question is this: How can I make my window receive mouse events and handle them without getting activated?
P.S. I'm not very experienced in OS X development and this is my first Swift project, so excuses if this is a trivial problem.
You need to make your window an instance of NSPanel (or a subclass), include NSNonactivatingPanelMask in its styleMask, and set becomesKeyOnlyIfNeeded to true. (The style mask can be controlled in IB.) You probably also want it to be floating so it's always above normal windows, so set floatingPanel to true, too.

Property additionalActions of NSUserNotification seems not working?

To understand NSUserNotification better, I wrote a little test app playing with this class.
So far so good, except that no matter how hard I tried to feed the additionalActions property with array of NSUserNotificationAction objects, it never showed any difference but only one action button and a close one.
My expectation for this property is that the notification would show a pull-down menu containing the additional buttons I offer as it does in the Mac App Store update notifications.
Am I missing something? Or are you having the same problem, since it is a bug awaiting Apple to tackle?
Can you please try to click and hold down the action button in your notification? Does it show a drop-down menu of additionalActions?
Update
As it turns out, you can show the little chevron next to the action button by setting a true value for the private _alwaysShowAlternateActionMenu key on the notification. In Swift 3, it would look like this:
notification.setValue(true, forKey: "_alwaysShowAlternateActionMenu")
However, as I mentioned this is a private API and I strongly advise against using it if you want to distribute your App through the Mac App Store.
It is probably a bug. Setting up additionalActions will create the list, but not the little arrow icon. Holding down on actionButton will show the menu with the number of actions you set.
Besides setting additionalActions will cause several other problems. I will save this for another question.
Refer to another question.
show NSUserNotification additionalActions on click
P.S. I am using El Capitan APIs