Merge upstream/main into main

This commit is contained in:
Andras Laszlo committed 2026-10-16 17:16:20 +02:00
commit d8b1eaf23c
4 files changed
+126 -4

No files matched your search

+7
View File
@@ -34,8 +34,15 @@ darling shell env DYLD_FRAMEWORK_PATH=/Users/me/RuntimeFrameworks \
/Volumes/SystemRoot/path/to/darling-lol/build/riot-coretext-font-list-check
darling shell env DYLD_FRAMEWORK_PATH=/Users/me/RuntimeFrameworks \
/Volumes/SystemRoot/path/to/darling-lol/build/riot-window-layout-check
darling shell env DYLD_FRAMEWORK_PATH=/Users/me/RuntimeFrameworks \
/Volumes/SystemRoot/path/to/darling-lol/build/riot-display-modes-check
```
`riot-display-modes-check` (built by `build-riot-display-modes-check.py`) expects `DISPLAY_MODES_CHECK pass=1`. It checks two things for the main display, display 0 and an unknown display:
- `CGDisplayCopyAllDisplayModes` never returns NULL. League passes the id from `[[window screen] deviceDescription]` (0 while the window is off every screen) straight to `CFArrayGetCount`, and NULL crashed it.
- `CGDisplayScreenSize` returns a nonzero size (`SCREEN_SIZE ... pass=1`). It returned 0×0 for any display with EDID. League divides by this size for its camera aspect ratio, so the view-projection matrix's x row became NaN and every 3D vertex was discarded. The scene then showed only its blue clear colour, and world clicks did nothing. This was found with a RenderDoc capture and vertex shader debugging.
Expected: `CORETEXT_FONT_LIST pass=1` with nonzero family/face counts (306/1124 on the development host), `VIEW_LAYER_RESIZE initial=1600x900 pass=1`, `NATIVE_RESIZE_ORDER size=1600x900 pass=1` `CONTENT_SIBLING_RESIZE ... pass=1` and `WINDOW_LAYOUT_CHECK ... pass=1`.
The font probe reproduces Chromium's installed-family enumeration, mandatory family matching and localized-name lookup with a null language output. It checks ownership of the single-match result and that a nonexistent mandatory family produces no substitute. The resize probe checks backing-layer bounds immediately after frame/bounds changes, including a scaled view and a child layer, without relying on input or coordinate conversion to refresh them. It also verifies that native parent size is current during child layout, and that adding an overlay sibling after the content view does not redirect subsequent content resizing into that overlay. The old sibling selection left content at 1600×900 while stretching the 30×20 overlay to 1280×720; the corrected layout resizes the content and preserves the overlay. Before the fixes, these checks report a stale 1280×720 layer and native parent after a 1600×900 resize. The `FRAME_SIZE_HOOK` check uses a subclass whose `setFrameSize:` publishes its viewport size. It checks growth and shrinkage through parent autoresizing, direct `setFrame:`, and direct `setFrameSize:`. Before component-setter dispatch was corrected only the final direct size setter reached the subclass (one callback); afterward all four updates do, with current geometry visible inside the callback. No probe launches or contacts Riot/League. The user confirmed that the language dropdown and League window resizing work after the final X11 correction (2026-10-15). The practice-tool crash remains unresolved.
+64 -4
View File
@@ -5781,7 +5781,7 @@ index db8869c8..6fea5107 100644
+ CGContextSetTextPosition(c, savedPosition.x, savedPosition.y);
}
diff --git a/CoreGraphics/CGDirectDisplay.m b/CoreGraphics/CGDirectDisplay.m
index e213b066..569d77f2 100644
index e213b066..ea0bc264 100644
--- a/CoreGraphics/CGDirectDisplay.m
+++ b/CoreGraphics/CGDirectDisplay.m
@@ -53,6 +53,29 @@ static NSDisplay *currentDisplay(void) {
@@ -5939,7 +5939,26 @@ index e213b066..569d77f2 100644
}
CGDirectDisplayID CGDisplayMirrorsDisplay(CGDirectDisplayID display) {
@@ -341,11 +366,10 @@ static NSData *edidForDisplay(CGDirectDisplayID displayId) {
@@ -319,10 +344,15 @@ CFStringRef CGDisplayModeCopyPixelEncoding(CGDisplayModeRef mode) {
CFArrayRef CGDisplayCopyAllDisplayModes(CGDirectDisplayID displayIndex,
CFDictionaryRef options)
{
+ /* League reads the id from [[window screen] deviceDescription], which is
+ * 0 while the window is off every screen, and passes the result straight
+ * to CFArrayGetCount. Fall back to the main display, then to an empty
+ * array, so callers never get NULL. */
NSDisplay *display = currentDisplay();
- if (!display)
- return NULL;
- return (CFArrayRef)[[display modesForScreen: displayIndex - 1] retain];
+ NSArray *modes = [display modesForScreen: displayIndex - 1];
+ if (modes == nil)
+ modes = [display modesForScreen: CGMainDisplayID() - 1];
+ return (CFArrayRef)[(modes ? modes : @[]) retain];
}
CGError CGDisplaySetDisplayMode(CGDirectDisplayID displayId,
@@ -341,11 +371,10 @@ static NSData *edidForDisplay(CGDirectDisplayID displayId) {
if (!display)
return nil;
@@ -5953,7 +5972,48 @@ index e213b066..569d77f2 100644
NSData *edid = [screen edid];
if (edid && [edid length] >= 16)
return edid;
@@ -474,7 +498,9 @@ CGError CGAssociateMouseAndMouseCursorPosition(boolean_t connected) {
@@ -354,17 +383,33 @@ static NSData *edidForDisplay(CGDirectDisplayID displayId) {
}
CGSize CGDisplayScreenSize(CGDirectDisplayID display) {
- printf("STUB %s\n", __PRETTY_FUNCTION__);
+ /* League divides by this size to get its camera aspect ratio; a zero size
+ * made every 3D vertex NaN (blue screen, world clicks ignored). Use the
+ * main display for an unknown id (an off-screen window reports 0). */
+ if (CGDisplayBounds(display).size.width <= 0)
+ display = CGMainDisplayID();
NSData *edid = edidForDisplay(display);
-
- if (!edid) {
- CGRect bounds = CGDisplayBounds(display);
-
- return bounds.size;
+ if (edid && [edid length] >= 128) {
+ const uint8_t *bytes = [edid bytes];
+ /* First detailed timing descriptor: image size in mm. */
+ double width = bytes[66] | ((bytes[68] & 0xf0) << 4);
+ double height = bytes[67] | ((bytes[68] & 0x0f) << 8);
+ /* DTV timings may encode only an aspect ratio in these fields. */
+ bool aspectRatioOnly = (width == 16 && height == 9) ||
+ (width == 4 && height == 3);
+ /* Basic display parameters: maximum image size in cm. */
+ if (width <= 0 || height <= 0 || aspectRatioOnly) {
+ width = bytes[21] * 10.0;
+ height = bytes[22] * 10.0;
+ }
+ if (width > 0 && height > 0)
+ return (CGSize){.width = width, .height = height};
}
- return (CGSize){.width = 0, .height = 0};
+ /* No usable EDID size: assume 96 dpi. */
+ CGSize pixels = CGDisplayBounds(display).size;
+ return (CGSize){.width = pixels.width * 25.4 / 96, .height = pixels.height * 25.4 / 96};
}
uint32_t CGDisplaySerialNumber(CGDirectDisplayID displayId) {
@@ -474,7 +519,9 @@ CGError CGAssociateMouseAndMouseCursorPosition(boolean_t connected) {
if (!display)
return kCGErrorInvalidConnection;
@@ -5964,7 +6024,7 @@ index e213b066..569d77f2 100644
return kCGErrorSuccess;
}
@@ -500,3 +526,38 @@ CFDictionaryRef CGDisplayCurrentMode(CGDirectDisplayID display) {
@@ -500,3 +547,38 @@ CFDictionaryRef CGDisplayCurrentMode(CGDirectDisplayID display) {
size_t CGDisplayModeGetPixelWidth(CGDisplayModeRef mode) {
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env python3
"""Build the CGDisplayCopyAllDisplayModes NULL-result probe against Darling's SDK."""
from pathlib import Path
import shlex
import subprocess
root = Path(__file__).resolve().parent.parent
folder = root / 'build/darling-src/build/src/external/cocotron/CoreGraphics'
flags = {}
for line in (folder / 'CMakeFiles/CoreGraphics.dir/flags.make').read_text().splitlines():
if line.startswith('C_') and ' = ' in line:
key, value = line.split(' = ', 1)
flags[key] = shlex.split(value)
obj = root / 'build/riot-display-modes-check.o'
subprocess.run(['clang', *flags['C_DEFINES'], *flags['C_INCLUDES'], *flags['C_FLAGS'],
'-Wno-macro-redefined', '-c', str(root / 'tools/riot-display-modes-check.c'),
'-o', str(obj)], check=True)
subprocess.run(['clang', '-target', 'x86_64-apple-macosx11.0', '-fuse-ld=lld', '-nostdlib',
'-isysroot', '@DARLING_SDK@', str(obj), '-lSystem',
'-framework', 'CoreGraphics', '-framework', 'CoreFoundation',
'-o', str(root / 'build/riot-display-modes-check')], check=True)
+34
View File
@@ -0,0 +1,34 @@
#include <CoreGraphics/CoreGraphics.h>
#include <stdio.h>
/* Exported by Darling's CoreGraphics but missing from its CGDirectDisplay.h. */
CFArrayRef CGDisplayCopyAllDisplayModes(CGDirectDisplayID display, CFDictionaryRef options);
/* League passes CGDisplayCopyAllDisplayModes' result straight to
* CFArrayGetCount; display id 0 comes from an off-screen window. */
static int check(CGDirectDisplayID display) {
CFArrayRef modes = CGDisplayCopyAllDisplayModes(display, NULL);
if (!modes) {
printf("DISPLAY_MODES display=%u result=NULL pass=0\n", display);
return 0;
}
printf("DISPLAY_MODES display=%u count=%ld\n", display, (long)CFArrayGetCount(modes));
CFRelease(modes);
return 1;
}
/* League divides by the physical size for its camera aspect ratio; {0,0}
* made every 3D vertex NaN. */
static int checkSize(CGDirectDisplayID display) {
CGSize size = CGDisplayScreenSize(display);
int ok = size.width > 0 && size.height > 0;
printf("SCREEN_SIZE display=%u size=%.0fx%.0fmm pass=%d\n", display, size.width, size.height, ok);
return ok;
}
int main(void) {
int pass = check(CGMainDisplayID()) & check(0) & check(0xffff);
pass &= checkSize(CGMainDisplayID()) & checkSize(0) & checkSize(0xffff);
printf("DISPLAY_MODES_CHECK pass=%d\n", pass);
return !pass;
}