From: shipmints Date: Tue, 4 Mar 2025 14:56:56 +0000 (-0500) Subject: Fix ns_make_monitor_attribute_list (bug#76691) X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=91a366c32e602e6399643585954286e05945ff73;p=emacs.git Fix ns_make_monitor_attribute_list (bug#76691) This is the NS implementation for 'display-monitor-attributes-list'. Change implementation from IORegistry to direct introspection of NSScreen. * src/nsfns.m (ns_make_monitor_attribute_list): Use localizedName selector on NSScreen. For anonymous displays, synthesize names of the form ("%dx%d@%d,%d" width height x y). (ns_get_name_from_ioreg) (ns_screen_name): Removed. (cherry picked from commit 9cc5f1c697c1a47470651ff4293f335eaa10ea9a) --- diff --git a/src/nsfns.m b/src/nsfns.m index b1ed0eff58a..b219064cdd1 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -2612,100 +2612,6 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height, return make_fixnum (ns_display_pixel_height (dpyinfo)); } -#ifdef NS_IMPL_COCOA - -/* Returns the name for the screen that OBJ represents, or NULL. - Caller must free return value. -*/ - -static char * -ns_get_name_from_ioreg (io_object_t obj) -{ - char *name = NULL; - - NSDictionary *info = (NSDictionary *) - IODisplayCreateInfoDictionary (obj, kIODisplayOnlyPreferredName); - NSDictionary *names = [info objectForKey: - [NSString stringWithUTF8String: - kDisplayProductName]]; - - if ([names count] > 0) - { - NSString *n = [names objectForKey: [[names allKeys] - objectAtIndex:0]]; - if (n != nil) name = xstrdup ([n UTF8String]); - } - - [info release]; - - return name; -} - -/* Returns the name for the screen that DID came from, or NULL. - Caller must free return value. -*/ - -static char * -ns_screen_name (CGDirectDisplayID did) -{ - char *name = NULL; - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 - if (CGDisplayIOServicePort == NULL) -#endif - { - mach_port_t masterPort; - io_iterator_t it; - io_object_t obj; - - /* CGDisplayIOServicePort is deprecated. Do it another (harder) way. - - Is this code OK for macOS < 10.9, and GNUstep? I suspect it is, - in which case is it worth keeping the other method in here? */ - - if (IOMasterPort (MACH_PORT_NULL, &masterPort) != kIOReturnSuccess - || IOServiceGetMatchingServices (masterPort, - IOServiceMatching ("IONDRVDevice"), - &it) != kIOReturnSuccess) - return name; - - /* Must loop until we find a name. Many devices can have the same unit - number (represents different GPU parts), but only one has a name. */ - while (! name && (obj = IOIteratorNext (it))) - { - CFMutableDictionaryRef props; - const void *val; - - if (IORegistryEntryCreateCFProperties (obj, - &props, - kCFAllocatorDefault, - kNilOptions) == kIOReturnSuccess - && props != nil - && (val = CFDictionaryGetValue(props, @"IOFBDependentIndex"))) - { - unsigned nr = [(NSNumber *)val unsignedIntegerValue]; - if (nr == CGDisplayUnitNumber (did)) - name = ns_get_name_from_ioreg (obj); - } - - CFRelease (props); - IOObjectRelease (obj); - } - - IOObjectRelease (it); - } -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 - else -#endif -#endif /* #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 */ -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 - name = ns_get_name_from_ioreg (CGDisplayIOServicePort (did)); -#endif - return name; -} -#endif /* NS_IMPL_COCOA */ - static Lisp_Object ns_make_monitor_attribute_list (struct MonitorInfo *monitors, int n_monitors, @@ -2825,7 +2731,25 @@ Internal use only, use `display-monitor-attributes-list' instead. */) m->work.height = (unsigned short) vfr.size.height; #ifdef NS_IMPL_COCOA - m->name = ns_screen_name (did); + m->name = NULL; + if ([s respondsToSelector:@selector(localizedName)]) + { + NSString *name = [s valueForKey:@"localizedName"]; + if (name != NULL) + { + m->name = xmalloc ([name lengthOfBytesUsingEncoding: NSUTF8StringEncoding] + 1); + strcpy(m->name, [name UTF8String]); + } + } + /* If necessary, synthesize a name of the following form: + %dx%d@%d,%d width height x y. */ + if (m->name == NULL) + { + char buf[25]; /* sufficient for 12345x78901@34567,90123 */ + snprintf (buf, sizeof(buf), "%ux%u@%d,%d", + m->work.width, m->work.height, m->work.x, m->work.y); + m->name = xstrdup (buf); + } { CGSize mms = CGDisplayScreenSize (did);