@@ -92,6 +92,7 @@ @interface WineApplicationController ()
92
92
@property (retain , nonatomic ) NSTimer * cursorTimer;
93
93
@property (retain , nonatomic ) NSCursor * cursor;
94
94
@property (retain , nonatomic ) NSImage * applicationIcon;
95
+ @property (copy , nonatomic ) NSString * applicationName; /* Whisky hack #9 */
95
96
@property (readonly , nonatomic ) BOOL inputSourceIsInputMethod;
96
97
@property (retain , nonatomic ) WineWindow* mouseCaptureWindow;
97
98
@@ -108,6 +109,7 @@ @implementation WineApplicationController
108
109
@synthesize keyboardType, lastFlagsChanged;
109
110
@synthesize displaysTemporarilyUncapturedForDialog, temporarilyIgnoreResignEventsForDialog;
110
111
@synthesize applicationIcon;
112
+ @synthesize applicationName; /* Whisky hack #9 */
111
113
@synthesize cursorFrames, cursorTimer, cursor;
112
114
@synthesize mouseCaptureWindow;
113
115
@synthesize lastSetCursorPositionTime;
@@ -201,6 +203,7 @@ - (void) dealloc
201
203
[cursor release ];
202
204
[screenFrameCGRects release ];
203
205
[applicationIcon release ];
206
+ [applicationName release ]; /* Whisky hack #9 */
204
207
[clipCursorHandler release ];
205
208
[cursorTimer release ];
206
209
[cursorFrames release ];
@@ -384,6 +387,14 @@ - (void) transformProcessToForeground:(BOOL)activateIfTransformed
384
387
[self changeEditMenuKeyEquivalentsForWindow: [NSApp keyWindow ]];
385
388
386
389
[NSApp setApplicationIconImage: self .applicationIcon];
390
+
391
+ /* Whisky hack #9 */
392
+ // Set application name
393
+ NSString * appName = [NSString stringWithFormat: kAppNameText , self .applicationName];
394
+ bool success = [self setProcessName: appName];
395
+ if (!success)
396
+ NSLog (@" Failed to set process name to %@ " , appName);
397
+ [appName release ];
387
398
}
388
399
}
389
400
@@ -833,6 +844,110 @@ - (void) sendDisplaysChanged:(BOOL)activating
833
844
macdrv_release_event (event);
834
845
}
835
846
847
+ /* Whisky hack #9 */
848
+ - (BOOL ) setProcessName:(NSString *)name
849
+ {
850
+ // Convert the name to a CFString
851
+ CFStringRef cfName = (CFStringRef )name;
852
+
853
+ // Must be called on the main thread
854
+ if (![NSThread isMainThread ]) {
855
+ NSLog (@" setProcessName: must be called on the main thread" );
856
+ return false ;
857
+ }
858
+
859
+ // New name can't be NULL or empty
860
+ if (!cfName || CFStringGetLength (cfName) == 0 ) {
861
+ NSLog (@" setProcessName: Invalid process name" );
862
+ return false ;
863
+ }
864
+
865
+ // Private types used in calls to launch services
866
+ typedef CFTypeRef PrivateLaunchRef;
867
+ typedef PrivateLaunchRef (*LSGetCurrentApplicationASNType)(void );
868
+ typedef OSStatus (*LSSetApplicationInformationItemType)(
869
+ int ,
870
+ PrivateLaunchRef,
871
+ CFStringRef ,
872
+ CFStringRef ,
873
+ CFDictionaryRef
874
+ );
875
+
876
+ // Static so we can reuse the same function pointers
877
+ static bool initialized = false ;
878
+ static LSGetCurrentApplicationASNType getCurrentAppASNFunc = NULL ;
879
+ static LSSetApplicationInformationItemType setAppInfoFunc = NULL ;
880
+ static CFStringRef launchServicesDisplayNameKey = NULL ;
881
+
882
+ // Initialize the function pointers
883
+ if (!initialized) {
884
+ initialized = true ;
885
+
886
+ // Get the bundle for the LaunchServices framework
887
+ CFBundleRef launchServicesBundle = CFBundleGetBundleWithIdentifier (CFSTR (" com.apple.LaunchServices" ));
888
+ if (!launchServicesBundle) {
889
+ NSLog (@" setProcessName: Failed to get LaunchServices bundle" );
890
+ return false ;
891
+ }
892
+
893
+ // Get the function pointers
894
+ getCurrentAppASNFunc = (LSGetCurrentApplicationASNType)(
895
+ CFBundleGetFunctionPointerForName (launchServicesBundle, CFSTR (" _LSGetCurrentApplicationASN" ))
896
+ );
897
+ if (!getCurrentAppASNFunc) {
898
+ NSLog (@" setProcessName: Failed to get _LSGetCurrentApplicationASN in LaunchServices" );
899
+ return false ;
900
+ }
901
+ setAppInfoFunc = (LSSetApplicationInformationItemType)(
902
+ CFBundleGetFunctionPointerForName (launchServicesBundle, CFSTR (" _LSSetApplicationInformationItem" ))
903
+ );
904
+ if (!setAppInfoFunc) {
905
+ NSLog (@" setProcessName: Failed to get _LSSetApplicationInformationItem in LaunchServices" );
906
+ return false ;
907
+ }
908
+
909
+ // Get the display name key
910
+ const CFStringRef * displayNameKey = (const CFStringRef *)(
911
+ CFBundleGetDataPointerForName (launchServicesBundle, CFSTR (" _kLSDisplayNameKey" ))
912
+ );
913
+ launchServicesDisplayNameKey = displayNameKey ? *displayNameKey : NULL ;
914
+ if (!launchServicesDisplayNameKey) {
915
+ NSLog (@" setProcessName: Failed to get _kLSDisplayNameKey in LaunchServices" );
916
+ return false ;
917
+ }
918
+
919
+ // Force symbols to be loaded in the LaunchServices framework
920
+ ProcessSerialNumber psn = {0 , kCurrentProcess };
921
+ GetCurrentProcess (&psn);
922
+ }
923
+
924
+ // If any of the function pointers are NULL, we can't continue
925
+ if (!getCurrentAppASNFunc || !setAppInfoFunc || !launchServicesDisplayNameKey) {
926
+ NSLog (@" setProcessName: Failed to get all required LaunchServices functions" );
927
+ return false ;
928
+ }
929
+
930
+ // Get the current application's ASN
931
+ PrivateLaunchRef currentAppASN = getCurrentAppASNFunc ();
932
+
933
+ // Set the display name
934
+ OSErr err = setAppInfoFunc (
935
+ -2 , // WebKit uses -2
936
+ currentAppASN,
937
+ launchServicesDisplayNameKey,
938
+ cfName,
939
+ NULL // Output parameter
940
+ );
941
+
942
+ // Log any errors
943
+ if (err != noErr ) {
944
+ NSLog (@" setProcessName: Failed to set display name: %d " , err);
945
+ return false ;
946
+ }
947
+
948
+ return true ;
949
+ }
950
+
836
951
// We can compare two modes directly using CFEqual, but that may require that
837
952
// they are identical to a level that we don't need. In particular, when the
838
953
// OS switches between the integrated and discrete GPUs, the set of display
@@ -1176,6 +1291,13 @@ - (void) setApplicationIconFromCGImageArray:(NSArray*)images
1176
1291
self.applicationIcon = nsimage;
1177
1292
}
1178
1293
1294
+ /* Whisky hack #9 */
1295
+ - (void ) setApplicationName:(NSString *)name
1296
+ {
1297
+ [applicationName release ];
1298
+ applicationName = [name copy ];
1299
+ }
1300
+
1179
1301
- (void ) handleCommandTab
1180
1302
{
1181
1303
if ([NSApp isActive ])
@@ -2634,6 +2756,22 @@ void macdrv_set_application_icon(CFArrayRef images, CFURLRef urlRef)
2634
2756
});
2635
2757
}
2636
2758
2759
+ /* Whisky hack #9 */
2760
+ /* **********************************************************************
2761
+ * macdrv_set_application_name
2762
+ *
2763
+ * Set the application name.
2764
+ */
2765
+ void macdrv_set_application_name (CFStringRef name)
2766
+ {
2767
+ NSString * nsName = (NSString *)name;
2768
+
2769
+ OnMainThreadAsync (^{
2770
+ WineApplicationController* controller = [WineApplicationController sharedController ];
2771
+ [controller setApplicationName: nsName];
2772
+ });
2773
+ }
2774
+
2637
2775
/* **********************************************************************
2638
2776
* macdrv_quit_reply
2639
2777
*/
0 commit comments