[Cocoa] Replace deprecated LSGetApplicationForInfo in Program.findProgram#3187
Conversation
3316bdb to
2608ab5
Compare
HannesWell
left a comment
There was a problem hiding this comment.
That's nice, thanks for that.
And it even needs less native code 🎉
One nitpick: If the years in the copyright headers are adjusted in some files, it would be nice to increment them in other files too.
2608ab5 to
48269e9
Compare
…gram
LSGetApplicationForInfo (deprecated macOS 10.10) and CFURLCreateFromFSRef
(deprecated macOS 10.9) are replaced by NSWorkspace APIs:
- On macOS 12.0+: UTType.typeWithFilenameExtension: combined with
NSWorkspace.urlForApplicationToOpenContentType: for reliable content
type-based lookup, including third-party file types like .xlsx
- Fallback for older macOS: NSWorkspace.urlForApplicationToOpenURL:
with a dummy file URL carrying the extension
Adds a test asserting that findProgram(".txt") returns a non-null program
with a name on Windows and macOS. The test is skipped on Linux because
applications for MIME types may not be registered in Linux test environments.
48269e9 to
378b95a
Compare
The copyright years were actually not updated explicitly but auto-updated by SWT tooling. |
| } | ||
| } | ||
|
|
||
| static NSURL findAppURLForExtension(NSWorkspace workspace, NSString ext) { |
There was a problem hiding this comment.
| static NSURL findAppURLForExtension(NSWorkspace workspace, NSString ext) { | |
| private static NSURL findAppURLForExtension(NSWorkspace workspace, NSString ext) { |
| NSWorkspace workspace = NSWorkspace.sharedWorkspace(); | ||
| NSURL appURL = findAppURLForExtension(workspace, ext); |
There was a problem hiding this comment.
Wouldn't it be possible to just call NSWorkspace workspace = NSWorkspace.sharedWorkspace(); within the method instead of passing the returned object in as parameter?
Problem
Program.findProgram(String)on macOS used two deprecated native APIs:LSGetApplicationForInfo— deprecated since macOS 10.10, used to find the default application for a file extension by querying Launch ServicesCFURLCreateFromFSRef— deprecated since macOS 10.9, used to convert the returnedFSRefto aCFURLBoth of these also required the deprecated constants
kLSUnknownType,kLSUnknownCreator, andkLSRolesAll.Solution
The two deprecated calls are replaced by modern
NSWorkspaceAPIs:On macOS 12.0+ (primary path):
UTTypefor the file extension using[UTType typeWithFilenameExtension:](UniformTypeIdentifiers framework)[NSWorkspace URLForApplicationToOpenContentType:]This approach directly queries the Launch Services database by content type and reliably handles all file types, including third-party ones such as
.xlsx(Microsoft Excel), which the intermediateURLForApplicationToOpenURL:approach failed to resolve for non-existent dummy files on modern macOS.Fallback for macOS 10.6–11.x:
[NSWorkspace URLForApplicationToOpenURL:]with a dummy file URL carrying the target extensionChanges
NSWorkspace.java: Added two new methods following Java camelCase conventions:urlForApplicationToOpenURL(NSURL)— wraps the deprecated-but-still-functional macOS 10.6+ API for older systemsurlForApplicationToOpenContentType(long)— wraps the modern macOS 12.0+ APISelector.java/OS.java: Added the required Objective-C selectorsURLForApplicationToOpenURL:,URLForApplicationToOpenContentType:, andtypeWithFilenameExtension:OS.java: Removed native method declarations forLSGetApplicationForInfoandCFURLCreateFromFSRef, and their associated constantskLSUnknownType,kLSUnknownCreator,kLSRolesAllProgram.java: Replaced the deprecated two-step lookup with a call to the newfindAppURLForExtension()helper that applies the version-guarded strategy aboveos.c/os_stats.h: Regenerated to reflect the removed native methodsTest_org_eclipse_swt_program_Program.java: Addedtest_findProgramForTxt()asserting thatfindProgram(".txt")returns a non-null program with a non-empty name on Windows and macOS. The test is skipped on Linux because applications for MIME types may not be registered in Linux test environments.Related
Contributes to #3186
🤖 Created with Claude Code