I need to bring an iOS application to macOS using Catalyst. This application contain parts where it waits for a button to be pressed in the main thread, using
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
in a while loop to allow some dispatching while waiting. I know that this is not good style, but I need to convert this old source code and mentioned that when using this part of code under Catalyst, the main thread will not dispatch. So the button cannot be clicked, and a beach ball appears after two seconds.
I saw a similar construct for native macOS applications:
NSEvent *event= [[NSApplication sharedApplication] nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate dateWithTimeIntervalSinceNow:0.1] inMode:NSDefaultRunLoopMode dequeue:YES];
if (event) {
[[NSApplication sharedApplication] sendEvent:event]; }
but I do not have access to NSEvent and NSApplication in a Catalyst environment.
Question: I there any code snippet which I can use to achieve the above? I do not want to completely rewrite old code if there is a solution for this. Any ideas or hints are highly appreciated.
Thank you!
Markus
AppKit
RSS for tagConstruct and manage a graphical, event-driven user interface for your macOS app using AppKit.
Post
Replies
Boosts
Views
Activity
Hello.
In my app, I use RegisterEventHotkey to implement global keyboard shortcuts to trigger actions.
Up until macOS Sequoia, I was able to use a keyboard shortcut with option and shift as the modifiers, like option shift 2 (⌥ ⇧ 2).
Now, on macOS Sequoia, using RegisterEventHotkey to register a hotkey with those exact modifiers (option and shift), regardless of the key, fails with the error -9868 (eventInternalErr).
Is this a documented and wanted change, or is this a bug? Other modifier keys (just command, command option, command shift, command control, control shift, etc), all work.
Any insight into this would be appreciated. (Feedback filed: FB15163561)
Thank you,
Matthias
Bit of a stream of consciousness below. I discovered after writing all that that I needed to switch width & height when setting values, and print landscape. That gets things to print as expected. But I really need to be able to set the Brother's notion of tape width in the Basic Options portion of the print panel.
I've got this Brother QL-800 USB label printer that takes spools of either die-cut labels, or continuous paper of a given width. It can cut between labels or the continuous paper at any point.
My app is intended to print small labels for small parts drawers. The app has a DB of parts, and I want to print dozens of unique labels of a specific height and width. Ideally, you'd set things up once, and then print one or more specific part labels without further UI interaction.
The NSPrintPanel is far too complex, and allows the user to ***** things up, so I'd like to forego it altogether.
I've written some simple code that does succeed in printing via the NSPrintPanel, but it’s positioning the text ultimately incorrectly.
I can't figure out how to properly size a view to print a label. I can get an NSPrintInfo object that knows the label printer is selected (e.g. it shows the right name for NSPrintInfo.printer.name). But it states the paperSize is (612.0, 792.0), which if I assume 72 ppi, comes out to 8.5" x 11", which this paper clearly is not.
func
printLabel()
{
Task
{
let printInfo = NSPrintInfo()
let printer = printInfo.printer
print("Paper size: \(printInfo.paperSize)")
// printInfo.paperSize = CGSize(width: 47 / 25.4 * 72.0, height: 12.0 / 25.4 * 72.0)
printInfo.topMargin = 0.0
printInfo.bottomMargin = 0.0
printInfo.leftMargin = 0.0
printInfo.rightMargin = 0.0
printInfo.orientation = .landscape
printInfo.isHorizontallyCentered = false
printInfo.isVerticallyCentered = false
printInfo.scalingFactor = 1.0
let view = NSHostingView(rootView: createLabelPrintView())
view.frame.size = CGSize(width: 25 / 25.4 * 72.0, height: 12.0 / 25.4 * 72.0)
let op = NSPrintOperation(view: view, printInfo: printInfo)
op.showsPrintPanel = true
op.showsProgressPanel = true
op.printPanel.options.insert(.showsPaperSize)
op.printPanel.options.insert(.showsOrientation)
op.run()
}
}
@ViewBuilder
func
createLabelPrintView()
-> some View
{
VStack(spacing: 0)
{
Text("Line 1")
Text("Line 2")
}
.padding(0)
}
If I set the pageSize explicitly (uncommenting the line above),
The printer offers a long list of available sizes (although none I've found corresponds to the 0.47"/12 mm x continuous spool). By the way, it never remembers the size I selected, and always reverts to 8.5 x 11, which it will then refuse to print, hanging in Print Center with an error about mismatched page sizes.
I don’t know why the available page sizes have multiple sizes that don’t seem to match. E.g. 0.47"
In the printer’s “Basic Options,” it shows the notion of a Width that's "not found," if I use a custom size:
I don't really understand where those printer options can be found and set.
Hmm, maybe I found a clue: I ran an NSPrintPanel by itself and examined the NSPrintInfo afterward:
let panel = NSPrintPanel()
panel.options.insert(.showsPaperSize)
panel.options.insert(.showsOrientation)
let result = await panel.beginSheet(using: printInfo, on: NSApplication.shared.windows.first!)
print("Result: \(result)")
print("Paper size: \(printInfo.paperSize)")
print("Settings: \(printInfo.printSettings)")
Paper size: (283.44000244140625, 82.08000183105469)
Settings: {
"AP_D_InputSlot" = "";
BrAutoTapeCut = ON;
BrBiDiPrint = ON;
BrBrightness = 0;
BrContrast = 0;
BrCutAtEnd = ON;
BrCutLabel = 1;
BrHalftonePattern = BrErrorDiffusion;
BrMargin = "3.0";
BrMultiColor = BrMultiColorMonochrome;
BrRedLevel = 0;
BrRemoveBlkSpace = OFF;
BrResolution = BrSpeed300x300dpi;
BrTapeLength = "69.1";
ColorModel = Gray;
Duplex = None;
PaperInfoIsSuggested = 0;
Resolution = 300x300dpi;
"com_apple_print_DialogDismissedBy" = Print;
"com_apple_print_DocumentTicket_PMSpoolFormat" = "application/pdf";
"com_apple_print_PDEsUsed" = "Printer Options";
"com_apple_print_PageToPaperMappingMediaName" = 29mm;
"com_apple_print_PageToPaperMappingType" = 1;
"com_apple_print_PrintSettings_PMCopies" = 1;
"com_apple_print_PrintSettings_PMCopyCollate" = 1;
"com_apple_print_PrintSettings_PMDestinationType" = 1;
"com_apple_print_PrintSettings_PMDuplexing" = 1;
"com_apple_print_PrintSettings_PMFirstPage" = 1;
"com_apple_print_PrintSettings_PMLastPage" = 2147483647;
"com_apple_print_PrintSettings_PMPageRange" = (
1,
2147483647
);
"com_apple_print_ticket_type" = "com.apple.print.PrintSettingsTicket";
"com_apple_print_totalPages" = 2147483647;
}
It has added a bunch of Br-prefixed keys that clearly correspond to some of the options in the UI. But I'm not sure if I can set those programmatically and get things to print the way I expect. And I don't see anything for tape width.
How do I get an NSPrintPanel to show the preview without an NSPrintOperation? I want to react to any changes the user might make before things go to print.
I have a simple cocoa project, it has the default files like AppDelegate.m, AppDelegate.h , ViewController.h and ViewController.m what I want is to set the Window title to the dimension of the current window and update it as the user resizes it.
My Storyboard has an Application Scene, a Window Controller Scene and a test Scene which contains my view:
how do I go about this? should my ViewController or AppController implement NSWindowDelegate ?
We have a xib file that contains a toolbar with some items in it. The toolbar has an IBOutlet defined in its files owner. Before macOS 15 - we were able to reach the items in the toolbar by using the items property.
The File Owner for the xib containing the toolbar is a NSViewController
e.g.
@IBOutlet var theToolbar: NSToolbar!
required init?(coder: NSCoder) {
super.init(coder: coder)
Bundle.main.loadNibNamed("ToolbarDesign", owner: self, topLevelObjects:nil)
}
and then later in code...
func getItems()
{
let items:[NSToolbarItem]? = mainRightToolbar?.items
}
Prior to macOS15 - items would contain the NSToolbarItems specified in the xib design. Now, in macOS 15 - the items array is not nil but doesn't contain any items either.
What needs to be don't for macOS15 specifically to enable the items property of NSToolbar to work again?
In the WWDC22 talk "What's new in TextKit and text views" (https://developer.apple.com/videos/play/wwdc2022/10090?time=408), it was announced (at minute 6:45) that TextKit 2 & NSTextList is supposed to be working on both UIKit and AppKit.
While NSTextLists are correctly rendering on iOS, they are not working on macOS. The paragraphs aren't inset and the numbers/bullets do not render in front of the list items.
Any help?
let textView = NSTextView(frame: self.view.bounds)
textView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(textView)
let safeArea = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
textView.topAnchor.constraint(equalTo: safeArea.topAnchor),
textView.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor),
textView.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor),
textView.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor)
])
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.textLists = [NSTextList(markerFormat: NSTextList.MarkerFormat("{decimal}."), options: 0)]
let attributedText = NSMutableAttributedString("Item 1\nItem 2\nItem 3\nItem 4f")
attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedText.length))
textView.textStorage?.setAttributedString(attributedText)
I have created a NSView inside the NSWindow. I m trying to identify when the view gets clicked by the user. For this I m using NSClickGestureRecognizer, but the registered method is not getting invoked. I have tried adding this for other widgets like button but it does not work either. Am I missing something?
class SelectionList :NSObject, NSTextFieldDelegate{
let containerView = NSView()
func createSelectionList (pWindow: NSWindow) {
// created container View
...
let clickRecognizer = NSClickGestureRecognizer()
clickRecognizer.target = self
clickRecognizer.buttonMask = 0x2 // right button
clickRecognizer.numberOfClicksRequired = 1
clickRecognizer.action = #selector(ClickGestured)
containerView .addGestureRecognizer(clickRecognizer)
}
@objc
func clickRecognizer() {
print("clicked")
}
}
I have an application with storyboard and I'm trying to set a constraint for the minimum size of my window (the view), but now matter what I do the constraint window is always grayed out, how do I go about this?
QLPreviewView was used in the app to display the file previews. But the following crash was happening.
Date/Time: 2024-09-13 22:03:59.056 +0530
OS Version: Mac OS X 10.13.6 (17G14042)
Report Version: 12
Anonymous UUID: 7CA3750A-2BDD-3FFF-5940-E5EEAE2E55F5
Time Awake Since Boot: 4300 seconds
System Integrity Protection: disabled
Notes: Translocated Process
Crashed Thread: 0
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: DYLD, [0x1] Library missing
Application Specific Information:
dyld: launch, loading dependent libraries
Dyld Error Message:
Library not loaded: /System/Library/Frameworks/QuickLookUI.framework/Versions/A/QuickLookUI
Referenced from: /private/var/folders/*/Notebook (Beta).app/Contents/MacOS/Notebook (Beta)
Reason: image not found
Process: Notebook (Beta) [4365]
Path: /private/var/folders/*/Notebook (Beta).app/Contents/MacOS/Notebook (Beta)
Identifier: com.zoho.notebook.macbeta
Version: 5.5 (55008)
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: Notebook (Beta) [4365]
User ID: 501
Date/Time: 2024-09-13 22:03:59.056 +0530
OS Version: Mac OS X 10.13.6 (17G14042)
Report Version: 12
Anonymous UUID: 7CA3750A-2BDD-3FFF-5940-E5EEAE2E55F5
Time Awake Since Boot: 4300 seconds
System Integrity Protection: disabled
Notes: Translocated Process
Crashed Thread: 0
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: DYLD, [0x1] Library missing
Application Specific Information:
dyld: launch, loading dependent libraries
Dyld Error Message:
Library not loaded: /System/Library/Frameworks/QuickLookUI.framework/Versions/A/QuickLookUI
Referenced from: /private/var/folders/*/Notebook (Beta).app/Contents/MacOS/Notebook (Beta)
Reason: image not found
So I have this program that displays events on the window using NSWindow and a NSTextField. Basically it tracks the mouse position and the keyboard state.
I created a simple class named MyEventWindow:
//
// MyEventWindow.h
// AppTest
#ifndef MyEventWindow_h
#define MyEventWindow_h
@interface MyEventWindow : NSWindow
{
}
@property(nonatomic, strong) NSTextField* label;
@property(nonatomic, strong) NSString* labelText;
- (BOOL)windowShouldClose:(id)sender;
- (instancetype) init;
- (void) setLabelText:(NSString *)labelText;
@end
@implementation MyEventWindow
-(instancetype) init
{
self = [super initWithContentRect:NSMakeRect(100, 100, 300, 300)
styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable)
backing:NSBackingStoreBuffered
defer:NO];
if( !self )
{
return nil;
}
[self setTitle: @"Event tracker"];
[self setIsVisible: YES];
_label = [[NSTextField alloc] initWithFrame:NSMakeRect(5, 100, 290, 100)];
[_label setBezeled: NO];
[_label setDrawsBackground: NO];
[_label setEditable: NO];
[_label setSelectable: YES];
NSFont *currentFont = [_label font];
NSFont *resizedFont = [NSFont fontWithName:[currentFont fontName] size:18];
NSFont *boldFont = [[NSFontManager sharedFontManager] convertFont:resizedFont toHaveTrait:NSFontBoldTrait];
// convert the bold font to have the italic trait
NSFont *boldItalicFont = [[NSFontManager sharedFontManager] convertFont:boldFont toHaveTrait:NSFontItalicTrait];
[_label setFont:boldItalicFont];
[_label setTextColor:[NSColor colorWithSRGBRed:0.0 green:0.5 blue:0.0 alpha:1.0]];
// attach label to the damn window
[[self contentView] addSubview: _label];
return self;
}
-(BOOL)windowShouldClose:(id)sender
{
return YES;
}
-(void) setLabelText:(NSString *)newText
{
[_label setStringValue: newText];
}
@end
#endif /* MyEventWindow_h */
Then in the main file I try to handle event loop manually:
//
// main.m
#import <Cocoa/Cocoa.h>
#import "MyEventWindow.h"
NSString* NSEventTypeToNSString(NSEventType eventType);
NSString* NSEventModifierFlagsToNSString(NSEventModifierFlags modifierFlags);
int main(int argc, char* argv[])
{
@autoreleasepool
{
[NSApplication sharedApplication];
MyEventWindow* eventWindow = [[MyEventWindow alloc] init];
[eventWindow makeKeyAndOrderFront:nil];
NSString* log = [NSString string];
// my own message loop
[NSApp finishLaunching];
while (true)
{
@autoreleasepool
{
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate: [NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES];
log = [NSString stringWithFormat:@"Event [type=%@ location={%d, %d} modifierFlags={%@}]", NSEventTypeToNSString([event type]), (int)[event locationInWindow].x, (int)[event locationInWindow].y, NSEventModifierFlagsToNSString([event modifierFlags])];
//NSLog(@"log: %@", log);
[eventWindow setLabelText: log];
[NSApp sendEvent:event];
//[NSApp updateWindows]; // redundant?
}
}
}
return 0;
}
NSString* NSEventTypeToNSString(NSEventType eventType)
{
switch (eventType)
{
case NSEventTypeLeftMouseDown: return @"LeftMouseDown";
case NSEventTypeLeftMouseUp: return @"LeftMouseUp";
case NSEventTypeRightMouseDown: return @"RightMouseDown";
case NSEventTypeRightMouseUp: return @"RightMouseUp";
case NSEventTypeMouseMoved: return @"MouseMoved";
case NSEventTypeLeftMouseDragged: return @"LeftMouseDragged";
case NSEventTypeRightMouseDragged: return @"RightMouseDragged";
case NSEventTypeMouseEntered: return @"MouseEntered";
case NSEventTypeMouseExited: return @"MouseExited";
case NSEventTypeKeyDown: return @"KeyDown";
case NSEventTypeKeyUp: return @"KeyUp";
case NSEventTypeFlagsChanged: return @"FlagsChanged";
case NSEventTypeAppKitDefined: return @"AppKitDefined";
case NSEventTypeSystemDefined: return @"SystemDefined";
case NSEventTypeApplicationDefined: return @"ApplicationDefined";
case NSEventTypePeriodic: return @"Periodic";
case NSEventTypeCursorUpdate: return @"CursorUpdate";
case NSEventTypeScrollWheel: return @"ScrollWheel";
case NSEventTypeTabletPoint: return @"TabletPoint";
case NSEventTypeTabletProximity: return @"TabletProximity";
case NSEventTypeOtherMouseDown: return @"OtherMouseDown";
case NSEventTypeOtherMouseUp: return @"OtherMouseUp";
case NSEventTypeOtherMouseDragged: return @"OtherMouseDragged";
default:
return [NSString stringWithFormat:@"%lu", eventType];
}
}
NSString* NSEventModifierFlagsToNSString(NSEventModifierFlags modifierFlags)
{
NSString* result = @"";
if ((modifierFlags & NSEventModifierFlagCapsLock) == NSEventModifierFlagCapsLock)
result = [result stringByAppendingString:@"CapsLock, "];
if ((modifierFlags & NSEventModifierFlagShift) == NSEventModifierFlagShift)
result = [result stringByAppendingString:@"NShift, "];
if ((modifierFlags & NSEventModifierFlagControl) == NSEventModifierFlagControl)
result = [result stringByAppendingString:@"Control, "];
if ((modifierFlags & NSEventModifierFlagOption) == NSEventModifierFlagOption)
result = [result stringByAppendingString:@"Option, "];
if ((modifierFlags & NSEventModifierFlagCommand) == NSEventModifierFlagCommand)
result = [result stringByAppendingString:@"Command, "];
if ((modifierFlags & NSEventModifierFlagNumericPad) == NSEventModifierFlagNumericPad)
result = [result stringByAppendingString:@"NumericPad, "];
if ((modifierFlags & NSEventModifierFlagHelp) == NSEventModifierFlagHelp)
result = [result stringByAppendingString:@"Help, "];
if ((modifierFlags & NSEventModifierFlagFunction) == NSEventModifierFlagFunction)
result = [result stringByAppendingString:@"Function, "];
return result;
}
in main I added a second @autoreleasepool inside the while loop it seemed to decrease memory usage significanly, however if I keep moving my mouse a lot the memory usage will still increase.
I don't think this should be happening since the labelText is being destroying and recreated each iteration, is something wrong with my code? Why do I have a memory leak here?
Any feedback regarding the code is also appreciated
Cheers
The performance of the PrintCore API on macOS Sequoia system has significantly deteriorated.
When switching between page options in the print dialog, the application hangs. It can be observed through Instruments that the execution time of PrintCore() is higher on the Sequoia system than on the Sonoma system.
479.00 ms 17.0% 0 s PMBaseObject::PMBaseObject(char const*)
456.00 ms 16.2% 0 s PMBaseObject::~PMBaseObject()
I'm using NSTextTable to format panels of stand-out text within body text. Paragraphs within the panel are handled as individual NSTextTableBlocks within the table. Each block is added to the NSMutableParagraphStyle that is part of the attributed string within the block's attributes. That's all fine and it works.
But...
Occasionally I see undrawn lines within the panel. These disappear (or sometimes appear) when the parent window (and thus the NSTextView holding the rendered attributed string) is resized. Lines do not always appear, and when they do they are not always in the same place. The height of the gap varies.
I see this behaviour with these panels and with tables. What's common to both cases is not only the use of NSTextTable and NSTextTableBlock etc., but crucially (I think) the use of block margins. If I disable margins (which looks OK for the panels, but isn't right for tables), the problem disappears.
So, a bug or (more likely) I'm missing a key part of view rendering or margin set up. But what? Code here: https://github.com/smittytone/PreviewMarkdown/blob/930f5f32aa0b3b77ec3f4f53436a79e10bb26f18/Markdown%20Previewer/Styler.swift#L882
Running 14.6.1 on an M3. I'm using TextKit 1 because I'm using an NSLayoutManager subclass to override certain text underlines (not used in panels as outlined above, or tables).
I created a simple application which displays a window with a sample text and I'm supposed to use an alert when the user chooses to close the application, if he presses ok in the alert the application will close, if he presses cancel it goes on.
So pretty simple code, I have a window class:
//
// MyWindow.h
// AppTest
//
// Created by sanya on 11/09/24.
//
#ifndef MyWindow_h
#define MyWindow_h
@interface Window : NSWindow
{
NSTextField* label;
}
- (instancetype)init;
- (BOOL)windowShouldClose:(id)sender;
@end
@implementation Window
-(instancetype)init
{
label = [[[NSTextField alloc] initWithFrame:NSMakeRect(5, 100, 290, 100)] autorelease];
[label setStringValue:@"Hello, World!"];
[label setBezeled:NO];
[label setDrawsBackground:NO];
[label setEditable:YES];
[label setSelectable:YES];
[label setTextColor:[NSColor colorWithSRGBRed:0.0 green:0.5 blue:0.0 alpha:1.0]];
[label setFont:[[NSFontManager sharedFontManager] convertFont:[[NSFontManager sharedFontManager] convertFont:[NSFont fontWithName:[[label font] fontName] size:45] toHaveTrait:NSFontBoldTrait] toHaveTrait:NSFontItalicTrait]];
[super initWithContentRect:NSMakeRect(0, 0, 300, 300) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable backing:NSBackingStoreBuffered defer:NO];
[self setTitle:@"Hello world (label)"];
[[self contentView] addSubview:label];
[self center];
[self setIsVisible:YES];
return self;
}
- (BOOL)windowShouldClose:(id)sender
{
BOOL bClose = NO;
CFOptionFlags responseFlags = 0;
// Display the alert
CFUserNotificationDisplayAlert(
0,
kCFUserNotificationNoteAlertLevel,
NULL,
NULL,
NULL,
CFSTR("Alert Title"),
CFSTR("This is a message displayed in the alert."),
CFSTR("OK"),
CFSTR("Cancel"),
NULL,
&responseFlags
);
if (responseFlags == kCFUserNotificationDefaultResponse)
{
NSLog(@"User clicked OK");
bClose = YES;
}
else if (responseFlags == kCFUserNotificationAlternateResponse)
{
NSLog(@"User clicked Cancel");
}
if( bClose )
[NSApp terminate:sender];
return bClose;
}
@end
#endif /* MyWindow_h */
And in the main function I just initialize it:
int main(int argc, const char * argv[])
{
[NSApplication sharedApplication];
[[[[Window alloc] init] autorelease] makeMainWindow];
[NSApp run];
}
It seems to work but if click 'Cancel' on the dialog , xcode gives me the following warning:
CLIENT ERROR: TUINSRemoteViewController does not override -viewServiceDidTerminateWithError: and thus cannot react to catastrophic errors beyond logging them
So i'm obviously not doing this in the correct way, how can I fix this?
Also, any feedback on this code as a whole is highly appreciated.
I have a SwiftUI View containing a PDFView from PDFKit (via NSViewRepresentable). When setting a new PDFDocument the view flashes briefly with the background color before displaying the new document.
Curiously the flashing is vastly reduced (but not eliminated) by calling layoutDocumentView() which should already be called from setDocument according to its documentation.
struct SheetView: NSViewRepresentable {
var pdf: PDFDocument?
func makeNSView(context: Context) -> PDFView {
let pdfView = PDFView()
pdfView.displaysPageBreaks = false
pdfView.displayMode = .singlePage
pdfView.pageShadowsEnabled = false
pdfView.autoScales = true
return pdfView
}
func updateNSView(_ pdfView: PDFView, context: Context) {
if pdf != pdfView.document {
pdfView.document = pdf
pdfView.layoutDocumentView() // reduces flashing but does not eliminate it
}
}
}
Hello,
I want to subclass NSDocumentController, but I could not find the information in Apple document how to subclass.
According to ChatGPT, it can be instantiated by [MyDocumentController sharedDocumentController]; before NSApplicationMain() as the following code. It seems working well in my test environment.
int main(int argc, const char * argv[]) {
[MyDocumentController sharedDocumentController];
NSApplicationMain(argc, argv);
}
But, I am not sure whether it is officially correct to instantiate so early (before calling NSApplicationMain).
Is there any official information what is correct way to instantiate subclass of NSDocumentController?
Hello. What API or framework to use to simulate a mouse click on an iPad connected as an external display?
An iPad connected to the Mac via USB in a mode "Linked keyboard and mouse".
What is the way to simulate a mouse click at a specific coordinate at such a display?
So far I tried to simulate a click with CGEvent like so
if
let eventDown = CGEvent(mouseEventSource: source, mouseType: .leftMouseDown, mouseCursorPosition: point, mouseButton: .left),
let eventUp = CGEvent(mouseEventSource: source, mouseType: .leftMouseUp, mouseCursorPosition: point, mouseButton: .left)
{
eventDown.post(tap: .cghidEventTap)
usleep(500_000)
eventUp.post(tap: .cghidEventTap)
}
but it seems it does not work even on the main display. I set the point to the coordinate outside of the app window so that on a click another app should be focused but it does not happen on a simulated click.
I also tried to find a way to get a mouse coordinate on the external screen with addLocalMonitorForEvents. If I listen for the event
NSEvent.addLocalMonitorForEvents(matching: [.mouseMoved]) { event in
debugPrint("NSEvent.mouseLocation:", NSEvent.mouseLocation)
return event
}
it only works when the cursor is on the main screen and stops reporting as soon as the mouse enters the iPad.
So, any advice is welcomed on which direction I should look.
I am trying to get the list of printers using NSPrinter.printerNames, but it doesn't return any items.
static func getPrinterList() -> [(name: String, isAvailable: Bool)] {
let printerNames = NSPrinter.printerNames
return printerNames.map { name in
let isAvailable = NSPrinter(name: name) != nil
return (name: name, isAvailable: isAvailable)
}
}
The printerNames is a empty string array.
I checked the settings for printers and screens, and there is a printer device listed.
I need to set something else?
The new window resizing and placement feature of macOS Sequoia is not working in my application, and I don't know why. What's worse, I haven't consulted any relevant documents.
I have two NSTextField as an accessoryView of NSSavePanel. When I try to change focus in between them with a caps lock on the whole panel will crash. This will also happen when NSTextField if focused with caps lock on and i press cmd+tab (app switching).
This happens on Sonoma + Sequoia beta. On top I have noticed editing NSTextField in accessoryView is completely broken on Sonoma and I can only edit it ONLY when the textfiled is using bindings.
I am trying to find a workaround for the caps lock indicator being displayed. The only idea I have ATM is to observe NSApp.windows and look for TUINSWindow and force close it when it's visible.
Is there any other workaround to prevent this crash?
https://youtu.be/BCVjZH7684U
Sample code:
import Cocoa
class ViewController: NSViewController {
let savePanel = NSSavePanel()
override func viewDidLoad() {
super.viewDidLoad()
let view = NSGridView(views: [[NSTextField(string: "111111")], [NSTextField(string: "22222222")]])
savePanel.accessoryView = view
}
override func viewWillAppear() {
savePanel.runModal()
}
}
Crash report:
Cannot remove an observer <TUINSCursorUIController 0x600001844340> for the key path "visible" from <NSSavePanel 0x10ff05200> because it is not registered as an observer.
(
0 CoreFoundation 0x000000019a2522ec __exceptionPreprocess + 176
1 libobjc.A.dylib 0x0000000199d36158 objc_exception_throw + 60
2 Foundation 0x000000019b30436c -[NSObject(NSKeyValueObserverRegistration) _removeObserver:forProperty:] + 628
3 Foundation 0x000000019b3040a4 -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] + 136
4 TextInputUIMacHelper 0x0000000253d9e598 -[TUINSCursorUIController deactivate:] + 416
5 AppKit 0x000000019dbda3e4 -[NSTextInputContext deactivate] + 288
6 AppKit 0x000000019da3fff4 +[NSTextInputContext currentInputContext_withFirstResponderSync:] + 228
7 AppKit 0x000000019da4f084 -[NSView _setWindow:] + 692
8 AppKit 0x000000019db7d880 -[NSTextView(NSPrivate) _setWindow:] + 216
9 AppKit 0x000000019e4da778 __21-[NSView _setWindow:]_block_invoke.146 + 268
10 CoreAutoLayout 0x00000001a2aba588 -[NSISEngine withBehaviors:performModifications:] + 88
11 AppKit 0x000000019da4f4b4 -[NSView _setWindow:] + 1764
12 AppKit 0x000000019da7712c -[NSView removeFromSuperview] + 168
13 AppKit 0x000000019dc7c0e8 -[_NSKeyboardFocusClipView removeFromSuperview] + 56
14 AppKit 0x000000019dbc5474 -[NSWindow endEditingFor:] + 368
15 AppKit 0x000000019da770d0 -[NSView removeFromSuperview] + 76
16 AppKit 0x000000019dc7c0e8 -[_NSKeyboardFocusClipView removeFromSuperview] + 56
17 AppKit 0x000000019dc7be00 -[NSCell endEditing:] + 452
18 AppKit 0x000000019dc7b994 -[NSTextField textDidEndEditing:] + 264
19 CoreFoundation 0x000000019a1d2144 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 148
20 CoreFoundation 0x000000019a2663d8 ___CFXRegistrationPost_block_invoke + 88
21 CoreFoundation 0x000000019a266320 _CFXRegistrationPost + 440
22 CoreFoundation 0x000000019a1a0678 _CFXNotificationPost + 768
23 Foundation 0x000000019b2bd2c4 -[NSNotificationCenter postNotificationName:object:userInfo:] + 88
24 AppKit 0x000000019dc7b5fc -[NSTextView(NSSharing) resignFirstResponder] + 668
25 AppKit 0x000000019db2ca80 -[NSWindow _realMakeFirstResponder:] + 196
26 AppKit 0x000000019dcc1764 -[NSWindow _makeParentWindowHaveFirstResponder:] + 76
27 ViewBridge 0x00000001a296c8c0 -[NSAccessoryViewWindow makeFirstResponder:] + 80
28 AppKit 0x000000019dbdbb9c -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] + 3148
29 AppKit 0x000000019db67504 -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 288
30 AppKit 0x000000019db67210 -[NSWindow(NSEventRouting) sendEvent:] + 284
31 ViewBridge 0x00000001a296cecc -[NSAccessoryViewWindow sendEvent:] + 64
32 AppKit 0x000000019e2304f0 -[NSApplication(NSEventRouting) sendEvent:] + 1604
33 AppKit 0x000000019dc6df6c -[NSApplication _doModalLoop:peek:] + 276
34 AppKit 0x000000019dc6ce38 __35-[NSApplication runModalForWindow:]_block_invoke_2 + 56
35 AppKit 0x000000019dc6cde4 __35-[NSApplication runModalForWindow:]_block_invoke + 108
36 AppKit 0x000000019dc6c6b0 _NSTryRunModal + 100
37 AppKit 0x000000019dc6c570 -[NSApplication runModalForWindow:] + 292
38 AppKit 0x000000019e690490 -[NSSavePanel runModal] + 340
39 SavePanelAccessory 0x0000000100435ad4 $s18SavePanelAccessory14ViewControllerC14viewWillAppearyyF + 60
40 SavePanelAccessory 0x0000000100435b0c $s18SavePanelAccessory14ViewControllerC14viewWillAppearyyFTo + 36
41 AppKit 0x000000019db387f4 -[NSViewController _sendViewWillAppear] + 32
42 AppKit 0x000000019db386bc -[NSViewController _windowWillOrderOnScreen] + 80
43 AppKit 0x000000019e4e7b38 -[NSView _windowWillOrderOnScreen] + 56
44 AppKit 0x000000019e4e7ba4 -[NSView _windowWillOrderOnScreen] + 164
45 AppKit 0x000000019db38570 -[NSWindow _doWindowWillBeVisibleAsSheet:] + 40
46 AppKit 0x000000019e4fc418 -[NSWindow _reallyDoOrderWindowAboveOrBelow:] + 1028
47 AppKit 0x000000019e4fcfec -[NSWindow _reallyDoOrderWindow:] + 64
SHORTENED