diff options
| author | shipmints | 2025-03-04 09:56:56 -0500 |
|---|---|---|
| committer | Alan Third | 2025-06-02 18:34:10 +0100 |
| commit | 9cc5f1c697c1a47470651ff4293f335eaa10ea9a (patch) | |
| tree | bdd3a1c0facd1e92b5c00e16e28bd61294f4fa42 | |
| parent | 55691c61d4af972b999bb97bffb46cb8571c912c (diff) | |
| download | emacs-9cc5f1c697c1a47470651ff4293f335eaa10ea9a.tar.gz emacs-9cc5f1c697c1a47470651ff4293f335eaa10ea9a.zip | |
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.
| -rw-r--r-- | src/nsfns.m | 114 |
1 files changed, 19 insertions, 95 deletions
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, | |||
| 2612 | return make_fixnum (ns_display_pixel_height (dpyinfo)); | 2612 | return make_fixnum (ns_display_pixel_height (dpyinfo)); |
| 2613 | } | 2613 | } |
| 2614 | 2614 | ||
| 2615 | #ifdef NS_IMPL_COCOA | ||
| 2616 | |||
| 2617 | /* Returns the name for the screen that OBJ represents, or NULL. | ||
| 2618 | Caller must free return value. | ||
| 2619 | */ | ||
| 2620 | |||
| 2621 | static char * | ||
| 2622 | ns_get_name_from_ioreg (io_object_t obj) | ||
| 2623 | { | ||
| 2624 | char *name = NULL; | ||
| 2625 | |||
| 2626 | NSDictionary *info = (NSDictionary *) | ||
| 2627 | IODisplayCreateInfoDictionary (obj, kIODisplayOnlyPreferredName); | ||
| 2628 | NSDictionary *names = [info objectForKey: | ||
| 2629 | [NSString stringWithUTF8String: | ||
| 2630 | kDisplayProductName]]; | ||
| 2631 | |||
| 2632 | if ([names count] > 0) | ||
| 2633 | { | ||
| 2634 | NSString *n = [names objectForKey: [[names allKeys] | ||
| 2635 | objectAtIndex:0]]; | ||
| 2636 | if (n != nil) name = xstrdup ([n UTF8String]); | ||
| 2637 | } | ||
| 2638 | |||
| 2639 | [info release]; | ||
| 2640 | |||
| 2641 | return name; | ||
| 2642 | } | ||
| 2643 | |||
| 2644 | /* Returns the name for the screen that DID came from, or NULL. | ||
| 2645 | Caller must free return value. | ||
| 2646 | */ | ||
| 2647 | |||
| 2648 | static char * | ||
| 2649 | ns_screen_name (CGDirectDisplayID did) | ||
| 2650 | { | ||
| 2651 | char *name = NULL; | ||
| 2652 | |||
| 2653 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 | ||
| 2654 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 | ||
| 2655 | if (CGDisplayIOServicePort == NULL) | ||
| 2656 | #endif | ||
| 2657 | { | ||
| 2658 | mach_port_t masterPort; | ||
| 2659 | io_iterator_t it; | ||
| 2660 | io_object_t obj; | ||
| 2661 | |||
| 2662 | /* CGDisplayIOServicePort is deprecated. Do it another (harder) way. | ||
| 2663 | |||
| 2664 | Is this code OK for macOS < 10.9, and GNUstep? I suspect it is, | ||
| 2665 | in which case is it worth keeping the other method in here? */ | ||
| 2666 | |||
| 2667 | if (IOMasterPort (MACH_PORT_NULL, &masterPort) != kIOReturnSuccess | ||
| 2668 | || IOServiceGetMatchingServices (masterPort, | ||
| 2669 | IOServiceMatching ("IONDRVDevice"), | ||
| 2670 | &it) != kIOReturnSuccess) | ||
| 2671 | return name; | ||
| 2672 | |||
| 2673 | /* Must loop until we find a name. Many devices can have the same unit | ||
| 2674 | number (represents different GPU parts), but only one has a name. */ | ||
| 2675 | while (! name && (obj = IOIteratorNext (it))) | ||
| 2676 | { | ||
| 2677 | CFMutableDictionaryRef props; | ||
| 2678 | const void *val; | ||
| 2679 | |||
| 2680 | if (IORegistryEntryCreateCFProperties (obj, | ||
| 2681 | &props, | ||
| 2682 | kCFAllocatorDefault, | ||
| 2683 | kNilOptions) == kIOReturnSuccess | ||
| 2684 | && props != nil | ||
| 2685 | && (val = CFDictionaryGetValue(props, @"IOFBDependentIndex"))) | ||
| 2686 | { | ||
| 2687 | unsigned nr = [(NSNumber *)val unsignedIntegerValue]; | ||
| 2688 | if (nr == CGDisplayUnitNumber (did)) | ||
| 2689 | name = ns_get_name_from_ioreg (obj); | ||
| 2690 | } | ||
| 2691 | |||
| 2692 | CFRelease (props); | ||
| 2693 | IOObjectRelease (obj); | ||
| 2694 | } | ||
| 2695 | |||
| 2696 | IOObjectRelease (it); | ||
| 2697 | } | ||
| 2698 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 | ||
| 2699 | else | ||
| 2700 | #endif | ||
| 2701 | #endif /* #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 */ | ||
| 2702 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 | ||
| 2703 | name = ns_get_name_from_ioreg (CGDisplayIOServicePort (did)); | ||
| 2704 | #endif | ||
| 2705 | return name; | ||
| 2706 | } | ||
| 2707 | #endif /* NS_IMPL_COCOA */ | ||
| 2708 | |||
| 2709 | static Lisp_Object | 2615 | static Lisp_Object |
| 2710 | ns_make_monitor_attribute_list (struct MonitorInfo *monitors, | 2616 | ns_make_monitor_attribute_list (struct MonitorInfo *monitors, |
| 2711 | int n_monitors, | 2617 | int n_monitors, |
| @@ -2825,7 +2731,25 @@ Internal use only, use `display-monitor-attributes-list' instead. */) | |||
| 2825 | m->work.height = (unsigned short) vfr.size.height; | 2731 | m->work.height = (unsigned short) vfr.size.height; |
| 2826 | 2732 | ||
| 2827 | #ifdef NS_IMPL_COCOA | 2733 | #ifdef NS_IMPL_COCOA |
| 2828 | m->name = ns_screen_name (did); | 2734 | m->name = NULL; |
| 2735 | if ([s respondsToSelector:@selector(localizedName)]) | ||
| 2736 | { | ||
| 2737 | NSString *name = [s valueForKey:@"localizedName"]; | ||
| 2738 | if (name != NULL) | ||
| 2739 | { | ||
| 2740 | m->name = xmalloc ([name lengthOfBytesUsingEncoding: NSUTF8StringEncoding] + 1); | ||
| 2741 | strcpy(m->name, [name UTF8String]); | ||
| 2742 | } | ||
| 2743 | } | ||
| 2744 | /* If necessary, synthesize a name of the following form: | ||
| 2745 | %dx%d@%d,%d width height x y. */ | ||
| 2746 | if (m->name == NULL) | ||
| 2747 | { | ||
| 2748 | char buf[25]; /* sufficient for 12345x78901@34567,90123 */ | ||
| 2749 | snprintf (buf, sizeof(buf), "%ux%u@%d,%d", | ||
| 2750 | m->work.width, m->work.height, m->work.x, m->work.y); | ||
| 2751 | m->name = xstrdup (buf); | ||
| 2752 | } | ||
| 2829 | 2753 | ||
| 2830 | { | 2754 | { |
| 2831 | CGSize mms = CGDisplayScreenSize (did); | 2755 | CGSize mms = CGDisplayScreenSize (did); |