So here's what I'm trying to do:
I want to build a small application that places an icon in my top bar in MacOS. When clicking this icon, it should switch the setting "System Preferences > Keyboard > Use keys F1, F2, ... as standard function keys". So it basically works like Caffeine just for a different setting.
This is my current code (which is still in the test phase):
class AppDelegate: NSObject, NSApplicationDelegate {
func test() {
let defaults = NSUserDefaults.standardUserDefaults().dictionaryRepresentation()
for value in defaults.keys {
print(value + " - " + String(defaults[value]))
}
}
func applicationDidFinishLaunching(aNotification: NSNotification) {
test()
}
}
The idea so far is to get the NSUserDefaults and get an overview of all they keys and the values stored in it. And here's my problem: How do I know which key I need to access the setting I want? I couldn't find any keys containing "keyboard" (I was expecting to see keys like "com.apple.keyboard.*").
I haven't found any documentation covering the range of possible keys to access certain settings.
If anyone could help me out I'd really appreciate it!
Thanks and have a good day!
Well, ironically I found it out just minutes after posting the question, but maybe this can help people to find other keys to access certain settings.
So first, the key I was looking for was "com.apple.keyboard.fnState".
Now here's how you can find keys you're looking for:
Before accessing the NSUserDefaults make sure to change the setting you try to manipulate at least once. This way you guarantee that an entry for this setting will be written to NSUserDefaults. And that's exactly why I wasn't able to find the key, because I never touched this setting (which could be seen as stupid considering what I'm trying to achieve, but that's up to you...).
On a side note: I still think it's pretty sad that Apple has no documentation whatsoever covering this topic.
Hope this helps others!
Related
I do not know, and cannot find, the standard technical term for the drag-select functionality when the alt/option button is pressed over an NSTextView.
When alt is pressed, the crosshair appears and text can be selected/highlighted in columns/vertically, as in Xcode.
I would like to disable this functionality in my NSTextViews, how can I do that please?
Digging into the disassembly of AppKit quickly reveals a hook which tells NSTextView whether the ALT+drag interaction should be enabled. It's the private method called _allowsMultipleTextSelectionByMouse. Altering its behavior does the trick but it is achievable only via private API. In this case, it should be pretty safe to do so.
There are following two ways for altering the aforementioned method:
Approach 1: NSUserDefaults
The method internally accesses the NSProhibitMultipleTextSelectionByMouse of NSUserDefaults. You can control the boolean value for this key on the app level. The downsides of this approach are:
It can possibly be reenabled by the users of your app (e.g. via the defaults command line tool).
It affects all instances of NSTextView in your app even those you don't necessarily want to alter.
Approach 2: Swizzling
The approach I decided to go with is a simple swizzle of this method in my subclass of NSTextView.
internal final class MyTextView: NSTextView {
internal static func initializeClass() {
try? MyTextView.swizzle(
Selector(("_allowsMultipleTextSelectionByMouse")),
with: #selector(getter: swizzled_allowsMultipleTextSelectionByMouse)
)
}
#objc dynamic internal var swizzled_allowsMultipleTextSelectionByMouse: Bool {
return false
}
}
And somewhere in the app bootstrapping code like the main function you have to trigger the class initialization code by MyTextView.initializeClass().
The code snippet above uses my own wrapper around the swizzling API but there are surely some libraries out there to use or you can follow the advices from this article by PSPDFKit.
I'm pretty new to programming in Swift, and I'd like to know if there is an easy way to add settings/preferences to my Cocoa application in Swift. If possible, I'd like a step by step guide. I mostly want to know how you store the user's preferences on disk and the code part. In my current code it will need to check which setting the user has chosen, and based on that perform an action. I'm using Xcode 7.1 and Swift 2. Thanks in advance!
The NSUserDefaults class is very easy to use in code, and its shared instance is readily available for binding to controls in Interface Builder.
For example, if I wanted to have an integer preference named "elmer" and set its value to 7, it's as easy as:
NSUserDefaults.standardUserDefaults().setInteger(7, forKey: "elmer")
To read the value back:
let elmer: Int = NSUserDefaults.standardUserDefaults().integerForKey("elmer")
To bind the value to a control in Interface Builder, set the Controller Key to "values", and the preference name for the Model Key Path:
I would recommend reading the "Preferences and Settings Programming Guide", and also to familiar yourself with the "NSUserDefaults Class Reference".
SWITF 5.x
The class changed the name so now you do:
UserDefaults.standard.set("1234", forKey: "userID")
To set a key that can hold any type. Or you can be type specific like this
UserDefaults.standard.bool(forKey: "IsConfigured")
The UI binding still working in the same fashion #ElmerCat well explained.
I've been searching and reading how firefox addons manages preferences, but all the samples I found involves GUI windows and other complex things I don't need.
What I need is, I have a list of some regex patterns, which needs to be updated often without user interaction whenever it's needed.
So I want to have the initial regex stored in the firefox addon like preferences but without any gui to edit them, and then be able to edit those hardcoded preferences.
Can someone show me an example on how to do this?
I don't want a full example, just how should I store these preferences and then edit them programmatically, without involving gui windows like all the .xul files I found does.
Something like this:
Components.utils.import("resource://gre/modules/Services.jsm");
// Reading the preference
var regexp = /foobar/; // default value
try
{
regexp = new RegExp(Services.prefs.getCharPref("extensions.myExtension.regexp"));
}
catch (e)
{
// Errors are expected, the preference might not exist yet
}
// Setting the preference
Services.prefs.setCharPref("extensions.myExtension.regexp", regexp.source);
You will be able to see this preference under about:config. More code examples
I have an NSMenuItem for which I would like to use the key equivalent Command-Option-C. However, when I set the key equivalent in IB, it does not get associated with the menu item when the app is actually run. The entry has no visible key equivalent, and that command does not invoke the item. Other key equivalents, like Shift-Control-C, do indeed work. The one I am trying to use does not conflict with any other key equivalent in the app.
What could be causing this seemingly random problem?
Command-Option-C works just fine here. Could it be that you have a custom keyboard shortcut set up in the keyboard system preferences that uses the same key combination? That would override the application's own shortcuts.
Is it possible the menu item in question is a "special" menu item which may be getting substituted at launch-time by the system? If so, it would be helpful to know whether you are able to set the same keyboard shortcut on a different, perhaps less interesting menu item.
I don't really have an authoritative understanding of which menu items may get this kind of treatment, but have a suspicion for example that maybe the "Help" menu, "Application" menu, or others that are common across many apps get tweaked or even regenerated dynamically, altering what you specified in the nib.
The easiest workaround I would shoot for first is to call setKeyEquvialent: directly on the menu time from code, after the nib has loaded. I couldn't tell from your Twitter summary if you had already tried this, and it also failed.
Check the tag on your menu item. If set to certain values it might Cocoa to override stuff
Check your system Prefs aren't overriding key bindings
Check the key binding doesn't already exist elsewhere in the menu hierarchy, especially in the edit menu
I'm having a bit of a strange issue that I can't quite figure out. I'm somewhat of a n00b to Interface Builder. What I am trying to do seems like it should be simple, but it's not working for some reason.
In interface builder I have a preferences window with a simple NSTextField. I have set the value binding to the Shared User Defaults Controller with the controller key "values" and model key "test". I build/run my app and open the preferences window, type some random value into said text field, close the window. Command-Q the app. Then in a shell i do a "defaults read com.xxx.yyy" for my app and the key and value are nowhere to be found. That being said, it seems like the next time I fire up the app and change the value it works but only if I switch focus off of the NSTextField before closing the window.
In the documentation for NSUserDefaults it says that the shared controller saves values immediately, am I missing something stupid here?
Thanks for any help.
I'm answering this a long time after it was asked in case others find it useful.
It sounds like you need to set "Continuously Updates Values" for the text field you've bound. Otherwise, the value is only sent and, accordingly, the preferences only updated when something happens to 'finalise' the edit. That's usually triggered by pressing Return and probably also happens when you switch focus away from the window (though I just tested this in one of my own applications and it didn't seem to commit the edit).