Construct and manage a graphical, event-driven user interface for your macOS app using AppKit.

AppKit Documentation

Post

Replies

Boosts

Views

Activity

notification about change visible window
Hello, I am trying to get a notification about change visible (top) window on Desktop. I am using NSWorkspaceDidActivateApplicationNotification notification and it works fine except situation of minimize current active application. Nothing is posted in notification center if active window is minimized. Are there any way to get some notification about change top window which is currently displayed on Desktop? Thank you in advance for your help!
0
0
377
Feb ’24
monitor input events
Hello, I need to monitor input events and convert keycode to symbol. E.g. convert kHIDUsage_KeyboardQ to symbol according to used keyboard layout. Are there any API to get current keyboard layout (language) in C++? If I understand correctly, the API TISGetInputSourceProperty() is deprecated. Are there any way to monitor keyboard layout changed? (some system notification in case of keyboard layout change) Are there any way to translate keycode to symbol except UCKeyTranslate() which is part of deprecated Unicode Utilities? Thank you in advance.
1
0
583
Feb ’24
NSWindow Suddenly Closes After NSTextField Ends Editing (By Clicking into Another NSTextField)
Configuration: I have a NSTextField (multiline) inside an NSWindow. I have another NSTextField (single line) inside an NSBox (which is in the same window). The multiline text field is first responder and is editing. I click on the single line text field inside the NSBox to edit that one. The NSWindow just closes. This is on Sonoma 14.2.1. I subclassed NSWindow and override the close method and put a breakpoint. Here's the call stack that leads to the window suddenly closing: #1 0x0000000189c73d90 in -[NSWindow __close] () #2 0x000000032343 in -[NSApplication(NSResponder) sendAction:to:from:] () #3 0x0000000189b543ac in -[NSControl sendAction:to:] () #4 0x0000000189b542f0 in __26-[NSCell _sendActionFrom:]_block_invoke () #5 0x0000000189b54218 in -[NSCell _sendActionFrom:] () #6 0x0000000189b5413c in -[NSButtonCell _sendActionFrom:] () #7 0x0000000189c4c508 in __29-[NSButtonCell performClick:]_block_invoke () #8 0x0000000189c4c264 in -[NSButtonCell performClick:] () #9 0x0000000189b545a8 in -[NSApplication(NSResponder) sendAction:to:from:] () #10 0x0000000189b543ac in -[NSControl sendAction:to:] () #11 0x0000000189befb48 in -[NSTextField textDidEndEditing:] () #12 0x0000000__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ () #13 0x000000018625c65c in ___CFXRegistrationPost_block_invoke () #14 0x000000018625c5a4 in _CFXRegistrationPost () #15 0x00000001861971dc in _CFXNotificationPost () #16 0x0000000187289ff0 in -[NSNotificationCenter postNotificationName:object:userInfo:] () #17 0x0000000189bef754 in -[NSTextView(NSSharing) resignFirstResponder] () #18 0x0000000189a9fab8 in -[NSWindow _realMakeFirstResponder:] () #19 0x0000000189b4f18c in -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] () #20 0x0000000189ada79c in -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] () #21 0x0000000189ada45c in -[NSWindow(NSEventRouting) sendEvent:] () #22 0x000000018a1879f4 in -[NSApplication(NSEventRouting) sendEvent:] () #23 0x0000000189dd6908 in -[NSApplication _handleEvent:] () #24 0x00000001899a1d74 in -[NSApplication run] () The mouse click is no where near the close button in the title bar.
2
0
581
Feb ’24
drawRect broken in Xcode 15/Sonoma
I'm manually placing a subclass of NSView into the parent view using addSubview:positioned:relativeTo. The dirtyRect passed to drawRect: is wildly incorrect. Can folks attempt to reproduce and file bugs? This is awfully close to the release of Sonoma, and I feel like folks with bezier curves (or maybe other drawing code?) in their NSView subclasses are going to experience problems. To reproduce, place a view (I'm using an NSImageView) as a subview within a view. Then, create a subclass of NSView and draw a bezier curve in the drawRect method. Add an instance of this subclass as a subview of your original view. I'm offsetting the x value for clarity. When I build with Xcode 15 and run on Ventura or earlier, I get the correct result. Or, if I build with Xcode 14.3 and run on Sonoma I get the correct result. However, when I build in Xcode 15 and run on the RC build of Sonoma, I get a whacky result. I get something like (origin = (x = -264, y = -146), size = (width = 480, height = 388)) for the dirtyRect in the error case, while the rect is supposed to be (origin = (x = 0, y = 0), size = (width = 48, height = 48)) (I'm basing the frame of the new view on the original image.) Thanks!
4
1
1.8k
Sep ’23
NSTextField problem in XCode 15.2
Because my MacOS app has a user-programmable interface, my coding creates lots of interface elements programmatically. Soon after an update to MacOS 14.3.1, I found some of these element (NSTextFields) did not draw correctly. I had not changed any code but the appearance changed for the worse (the text in the text field did not appear). I then noticed: The problem occurs when I compile in XCode 15.2 (15C500b) Version and run on computer with Sonoma 14.3.1 (23D60) If I instead compile in XCode Version 14.1 (14B47b) on Ventura 13.0.1 (22A400) and copy the app to my computer with Sonoma 14.3.1 (23D60)all works as expected. These results seem to imply XCode 15.2 does not compile correctly? Is this known issue or is there a fix?
2
0
739
Feb ’24
[NSView drawRect:] is called only once, however two different renderings are generated
I have a custom NSView embedded in a NSScrollView. [NSView drawRect:] is called once, when the window is created and displayed, and the rendering is exactly how it should be. Then I resize (shrink) the window, which does not make [NSView drawRect:] being called again, as no new part of my view needs to be drawn; however, the window's content is flushed again on screen, and the rendering is now different. How could this be possible? I am logging a message in my [NSView drawRect:] implementation, so I am absolutely certain that it is called only once in this scenario. Is it possible that a single drawing instruction ([NSBezierPath stroke], in this case) called only once actually produces two different rendered images, in two different drawing buffers, and that the buffer flushed to the screen can change depending on the size of the window?? Now, what is different in the rendering? Two things: antialiasing is performed differently (the line width is 0.25 pixel), correctly in the first case, and not very smoothly in the second case. I also changed [NSBezierPath setFlatness:], and this flatness is taken in account in the first case, and unchanged (default flatness) in the second case. When I continue to resize the window, enlarging then shrinking it, drawRect: is called when I enlarge it, and depending on the window size, sometimes I get the "correct" rendering, and sometimes the "wrong" one (for the whole view; it is not limited to the newly revealed area). I have a built-in display set to "more space", and an external non-retina monitor; with "desktop & dock" settings set to "displays have different Spaces", in case this has any impact on the situation.
3
0
483
Feb ’24
[macOS Sonoma] screencapture CLI no longer includes DPI information
Using the screencapture CLI on macOS Sonoma 14.0 (23A344) results in a 72dpi image file, no matter if it was captured on a retina display or not. For example, using screencapture -i ~/Desktop/test.png in Terminal lets me create a selective screenshot, but the resulting file does not contain any DPI metadata (checked using mdls ~/Desktop/test.png), nor does the image itself have the correct DPI information (should be 144, but it's always 72; checked using Preview.app). I noticed a (new?) flag option, -r, for which the documentation states: -r Do not add screen dpi meta data to captured file. Is that flag somehow automatically set? Setting it myself makes no difference and obviously results in a no-dpi-in-metadata and wrong-dpi-in-image file. The only two ways I got the correct DPI information in a resulting image file was using the default options (forced by -p): screencapture -i -p, and by making the capture go to the clipboard screencapture -i -c. Sadly, I can't use those in my case. Feedback filed: FB13208235 I'd appreciate any pointers, Matthias
4
2
1.4k
Sep ’23
NSTextField and NSAttributedString
I'm trying to put an attributed string in to an NSTextField the user creates in their document. I cannot use an NSTextView. The problem is once the textfield is created attributes cannot be edited. Also I work in Objective-c because reasons. So when the field is created this is the code used: [attribDict setObject:[self.editor.delegate foregroundColor] forKey:NSForegroundColorAttributeName]; [attribDict setObject:aFont forKey:NSFontAttributeName]; [attribDict setObject:[self.editor.delegate backgroundColor] forKey:NSBackgroundColorAttributeName]; [attribDict setObject:self.editor.delegate.strokeColor forKey:NSStrokeColorAttributeName]; [attribDict setObject:[NSNumber numberWithInt:-self.editor.delegate.strokeWidth] forKey:NSStrokeWidthAttributeName]; This part works if I set all the attributes before I create the textfield. But I need to be able to edit attributes on the string. For that I use this code: NSFont * aFont = [NSFont fontWithName:self.delegate.fontSelectorButton.title size:self.delegate.fontSize.intValue]; NSMutableDictionary * attribDict = [[NSMutableDictionary alloc]init]; [attribDict setObject:[self.delegate foregroundColor] forKey:NSForegroundColorAttributeName]; [attribDict setObject:aFont forKey:NSFontAttributeName]; [attribDict setObject:[self.delegate backgroundColor] forKey:NSBackgroundColorAttributeName]; [attribDict setObject:self.delegate.strokeColor forKey:NSStrokeColorAttributeName]; [attribDict setObject:[NSNumber numberWithInt:self.delegate.strokeWidth] forKey:NSStrokeWidthAttributeName]; [textShape updateTextAttributesFromDictionary:attribDict]; And finally this is called the change the string attributes: -(void)updateTextAttributesFromDictionary:(NSDictionary*)attribs { self.stringAttributes = attribs; NSMutableAttributedString * as = [[NSMutableAttributedString alloc]initWithAttributedString:self.myTextField.attributedStringValue]; [as beginEditing]; [as setAttributes:attribs range:NSMakeRange(0, as.length)]; [as endEditing]; self.myTextField.attributedStringValue = as; } I have tried just setting the new attributes and get nothing. The above code however gives me wildly unpredictable results. Sometimes the NSTextfield gets a background color that cannot be altered. Sometimes the text vanishes. Sometimes all attributes are lost, sometimes if I include a stroke color and width I get the stroke but no fill. That's the most common. Is there some fundimental NSTextField short coming I'm missing? Is there something I'm missing with NSAttributedString? Are NSAttributedStrings not compatible with NSTextField?
0
0
473
Feb ’24
Cocoa binding to NSButton messes with enabled state
When an NSButton's value and hidden state are bound to properties, changing either property enables the button. See example code: @interface MyClass () @property (nonatomic) BOOL buttonHidden; @property (nonatomic) BOOL buttonState; @end @implementation MyClass { __weak IBOutlet NSButton *button; // The button is in a view designed in IB } - (void)awakeFromNib { [super awakeFromNib]; [button bind:NSHiddenBinding toObject:self withKeyPath:@"buttonHidden" options:nil]; [button bind:NSValueBinding toObject:self withKeyPath:@"buttonState" options:nil]; button.enabled = NO; self.buttonHidden = NO; // This enables the button. If this line isn't executed, the buttons stays disabled. } @end Note that the issue occurs only of both properties are bound. I wonder if this is by design or a bug.
0
0
417
Feb ’24
`NSWorkspace.open` cannot deal with `xcodeproj`
Hello. I could wrong, but it seems NSWorkspace.open cannot open xcodeproj. When I try to do so in my sandboxed App, the App would hang the thread, causing NSWorkspace.open not responsive in the following calls. If called on the @main thread, then bad luck, it would cause dead lock. Callings this function on a normal file, such as .txt, or in a Command line Tool works perfectly. Is there anything obvious that I missed? I have permissions to read/write the files, as indicated by url.resourceValues(forKeys: [.isWritableKey]).isWritable.
1
0
341
Feb ’24
NSMenu.popUp(positioning:at:in:) doesn't enable menu items when opened inside modal window
In my app I use NSMenu.popUp(positioning:at:in:) for displaying a menu in response to the user clicking a button. But it seems that when the menu is opened inside a modal window, all the menu items are always disabled. Using NSMenu.popUpContextMenu(_:with:for:) instead works. What's the reason and what's the difference between the two methods? According to the documentation, one is for opening "popup menus" and the other for opening "context menus", but I cannot see an explanation of the difference between the two. @main class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { let window = NSWindow(contentViewController: ViewController()) NSApp.runModal(for: window) } } class ViewController: NSViewController { override func loadView() { let button = NSButton(title: "Click", target: self, action: #selector(click(_:))) view = NSView(frame: CGRect(x: 0, y: 0, width: 400, height: 400)) view.addSubview(button) } @objc func click(_ sender: Any?) { let menu = NSMenu(title: "") menu.addItem(withTitle: "asdf", action: #selector(asdf(_:)), keyEquivalent: "") menu.addItem(withTitle: "bla", action: nil, keyEquivalent: "") menu.items[0].target = self menu.items[1].target = self // NSMenu.popUpContextMenu(menu, with: NSApp.currentEvent!, for: view) // this works menu.popUp(positioning: nil, at: .zero, in: view) // this doesn't work } @IBAction func asdf(_ sender: Any) { print(0) } }
3
0
603
Feb ’24
Why does `DisclosureGroup` retains object references when content is hidden?
I'm displaying file structure using DisclosureGroup. And I encountered a memory leak problem. Code Node Node represents a file or a folder. isExpanded is used to indicate if the child nodes are visible. If true, it will find its child nodes, which are set into children. If false, it will clear children for releasing references. class Node: ObservableObject, Identifiable, Hashable, CustomStringConvertible { // ... @Published var name: String @Published var children: [Node]? @Published var isExpanded = false { willSet { if self.isFile { // This node represents a file. // It does not have any children. return } if newValue { if children?.count == 0 { DispatchQueue.main.async { // get child nodes self.children = childrenOf(self.url) } } } else { if children?.count != 0 { DispatchQueue.main.async { // collapse child nodes self.children?.forEach { child in child.isExpanded = false } // clear children when this node is collapsed self.children = [] } } } } } init(/*...*/) { // ... print("init \(name)") } deinit { // ... print("deinit \(name)") } // ... } For convenience, I print some messages when initializing Node and deinitializing Node. TreeNode TreeNode displays Node using DisclosureGroup. struct TreeNode: View { @ObservedObject var parent: Node @ObservedObject var node: Node var body: some View { if node.isFile { Text(node.name) } else { DisclosureGroup( isExpanded: $node.isExpanded, content: { if node.isExpanded { ForEach(node.children ?? []) { child in TreeNode(parent: node, node: child) } } }, label: { FolderNodeView(node: node) } ) } } } struct FolderNodeView: View { @ObservedObject var node: Node var body: some View { Label( title: { Text(node.name) }, icon: { Image(systemName: "folder.fill") } ) } } I use if node.isExpanded for lazy loading. When node.isExpanded is true, it will show node's children and print initialization messages. Otherwise, it will hide child nodes and print deinitialization messages. But unexpectedly it does not print any deinitialization messages when the node is collapsed. This indicates that it retains references and therefore these Node objects still exists in memory causing memory leak. Demo When the node is expanded, its child nodes will be displayed after loading is completed. The code works correctly. Then I collapsed the node, it didn't print any deinitialization messages. And when I expanded it again, it initialized new nodes and deinitialized the old nodes at this time. Deinitialization seems to be delayed. So I guess TreeNode retains references when content is hidden. Then I deleted TreeNode in ForEach. DisclosureGroup( isExpanded: $node.isExpanded, content: { if node.isExpanded { ForEach(node.children ?? []) { child in // TreeNode(parent: node, node: child) } } }, label: { FolderNodeView(node: node) } ) It cannot display the child nodes. But it released reference correctly. So the code works expectedly. After that, I tried to replace TreeNode with Text or Label. I found that none of them released references immediately when I collapsed the node. Why did this happen? Any idea how to fix it?
0
0
435
Feb ’24
Developer Program Documentation Access & Xcode
I am new to Apple 🍎 Development 👨‍💻 and Apple 🍎 Developer 👨‍💻 Forums. I have not joined the Apple 🍎 Developer 👨‍💻 Program yet. Is there any documentation 📖 that is only available to paid 💰 Apple 🍎 Developer 👨‍💻 Program members or is all of it freely available to those not (or not yet) in the paid 🚫💰 program? Is Xcode freely downloadable or does it require it be purchased like it used to be for non-program members?
2
0
467
Feb ’24
NSColorPanel: Control selection and order of NSColorLists
Hi folks, In my macOS app I’m using NSColorPanel to present color picking options to the user. Therefore I’m attaching various custom NSColorLists before showing the color panel. The panel is always presented with the „Apple“ color list active, and I found no method to select a different color list. In my app I could determine the most relevant color list and would like to preselect it instead of relying on a manual selection by the user. Is there any option to control the selected / active NSColorList of an NSColorPanel? Additionally - but that more a minor topic and probably a candidate for a bug report: Since some major macOS versions (maybe starting with macOS 13 „Ventura“?) the order of NSColorLists in the default NSColorPanel is random. In the past color palettes were listed in reverse order of their attachments via „attachColorList:“. Is there any way to control the order color palettes are listed by an NSColorPanel I just spent one of my TSIs for this question - as my Apple developer membership is renewed shortly - but maybe this community as some smart tip to share... Appreciate any help, Mattes
2
0
661
Feb ’24
Popover from NSToolbarItem in Mac Catalyst app
Hi, Inside a Mac Catalyst app, I need to display a popover starting from an NSToolbarItem contained inside the app toolbar (like the Apple Maps Mac app does, see below image). In order to do that, when I press the button I need to find the toolbar item view and use it as popover anchor. How can I find the view or frame of an NSToolbarItem on Mac Catalyst? A property that could help me is the NSToolbarItem "view" property (NSView), but that property has been marked has unavailable in Mac Catalyst. Any idea? Thank you
3
3
1.6k
Feb ’22
Unhidden subview outside of superview's bounds
I’ve finally changed my main development platform to macOS 14 Sonoma and almost immediately have I encountered something I consider being a bug. I searched for similar issues, but nowhere have I found any relevant information or help. The issue is rather funny; if you have a subview and, for whatever reason, it finds itself outside of its superview’s bounds, it remains visible, instead of being hidden. It’s like you have a window on your room wall, but still the interior of your room is visible outside of window’s borders :-) Here’s a simple Xcode project that explains what I’m talking about: https://zigz.ag/temp/SubviewBug/UnhiddenXcodeProject.zip Unpack and build this project, run the test application and see it yourself. However, there are some differences, regarding the Xcode/SDK version used to build the application and the macOS version it runs on. The project format is “Xcode 13.0” and MACOSX_DEPLOYMENT_TARGET = 13.0. Here you can find application bundle, build with Xcode 14: https://zigz.ag/temp/SubviewBug/UnhiddenXcode14Build.zip The relevant build parameters, as found in application's Info.plist are: BuildMachineOSBuild: 22G605 DTPlatformVersion: 13.3 DTSDKBuild: 22E245 DTXcode: 1431 DTXcodeBuild: 14E300c If you run it on both Ventura and Sonoma, you’ll see ti behaves as expected. However, here you can find application bundle, build with Xcode 15: https://zigz.ag/temp/SubviewBug/UnhiddenXcode15Build.zip The relevant build parameters, as found in application's Info.plist are: BuildMachineOSBuild: 23D56 DTPlatformVersion: 14.2 DTSDKBuild: 23C53 DTXcode: 1520 DTXcodeBuild: 15C500b Now, if you run this build on Ventura, you’ll see it behaves fine. Running it on Sonoma however, shows the behaviour I’m trying to explain; the ratio button titled “Two” remains visible, even though its superview shrinks and it goes out of its superview’s bounds. So, the issue is present only on Sonoma, if build with Xcode 15. The difference is visible even inside Interface Builder. Here is a short video of shrinking a superview in IB of Xcode 14, note how the “Two” radio button becomes invisible, as it goes outside of its superview’s bounds: https://zigz.ag/temp/SubviewBug/InterfaceBuilderXcode14.mov Here is the video of shrinking the same superview in IB of Xcode 15, the “Two” radio button remains visible regardless of its superview’s bounds: https://zigz.ag/temp/SubviewBug/InterfaceBuilderXcode15.mov Is this a bug? Or did I miss something in macOS 14 Sonoma SDK release notes, which would indicate from now on this is expected behaviour (highly unlikely)? -- Dragan
1
0
531
Feb ’24