mirror of
https://github.com/lucannez64/darling-lol.git
synced 2026-10-26 19:47:42 +00:00
Fix League client resizing and runtime compatibility
Fix X11 presentation handoff after resizing, preserve NSView size callbacks, and correct content and backing-layer geometry. Add CoreText font enumeration for the language dropdown and rebuild/install the matching runtime overlays. Correct CarbonCore Gestalt version queries and roll back proc_listpids for Vanguard testing. Document that VAN -101 can still recur. Include accumulated CoreAudio stream and AudioUnit corrections. Add standalone font, version, resize and publisher-handoff regressions. Record manual confirmation of the language dropdown and window resizing; all 29 pinned patches and the source/script audit validate.
This commit is contained in:
1 parent
87580c9862
commit
e94c3ce40f
18 files changed
+1879
-339
No files matched your search
@@ -15,6 +15,46 @@ python3 tools/riot-foundation-installer-offline-check.py
|
||||
|
||||
The patch check uses temporary base indexes and does not reset or modify the source checkout. The launcher check uses stub commands and never starts or contacts Riot or Darling. It checks installed-client and first-time-installer launches, strips inherited `DYLD_INSERT_LIBRARIES` even with the old VPX opt-in set, and preserves Darling runtime library/framework paths. The memory-installer check imports the installer and exercises its policy (default source is the prepared artifact; the artifact is never a destination of a different library) in temporary directories. The Foundation-installer check does the same for the overlay installer: it seeds a temporary framework from a stub SDK, replaces `Versions/C/Foundation`, keeps the standard symlinks, stages a backup, treats a re-run as current and refuses a non-Mach-O source. The installer handoff mock covers 28 scenarios, including HTTP 409, interrupted verification and preserving active downloads.
|
||||
|
||||
## CoreText font-list and AppKit resize regressions
|
||||
|
||||
After preparing the source and configuring the runtime tools:
|
||||
|
||||
```sh
|
||||
python3 build/runtime/tools/build-riot-coretext-runtime.py
|
||||
python3 build/runtime/tools/build-riot-appkit-runtime.py
|
||||
```
|
||||
|
||||
After installing and activating the runtime with both clients and the game closed, run the standalone probes (replace `me` and the checkout path):
|
||||
|
||||
```sh
|
||||
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
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
### Presentation publisher handoff
|
||||
|
||||
With clients closed, run `build/riot-client-resize-check --handoff` through Darling with the normal runtime overrides. This creates an owned window and two fixture frame slots. The live software owner first supplies a 1280×720 main frame, then switches to a 262×131 popup; another slot supplies the resized main frame without the software flag. The test samples its own window beyond the original frame extent and checks generation colors across growth and shrinkage. The old selector reports black at the 1600×900 sample; the correction passes all four sizes. Repeat with `RCLOL_XSHM=0` and with `DARLING_XSHM_LIBRARY` pointing to the normal transport to cover both paths. The fixtures remove their own frame slots on exit; they do not read client pixels or send input.
|
||||
|
||||
### Pixels after a window resize
|
||||
|
||||
`python3 build/runtime/tools/build-riot-client-resize-check.py` builds an independent AppKit window and IOSurface publisher. With clients closed and a display at least 1600×900, run it with the same framework/library overrides and `DARLING_XSHM_LIBRARY=/Users/me/libDarlingXShm.dylib`, `DARLING_CA_PRESENT_AT_COMMIT=1`, `DARLING_CA_SKIP_LOCAL_IOSURFACE_RENDER=1`. The default mode publishes software pixels. For the GPU path add `--gpu` and set `RCLOL_GPU_DIRECT_PRESENT=1 RCLOL_GPU_DIRECT_ASYNC=1` in the guest environment.
|
||||
|
||||
The probe cycles through 1280×720, 1600×900, 1024×576 and 1280×720. Each stage changes the frame color and samples its own X11 window near the bottom-right corner, beyond the original frame's extent when growing. It waits up to 2.5 seconds for presentation and prints `RESIZE_PIXEL ... pass=1` for every stage. This verifies presented pixels rather than only view properties. Success does not reproduce League's own resize callbacks; the reported League UI failure remains open, with the opt-in [geometry trace](TROUBLESHOOTING.md#language-dropdown-closes-riot-or-client-resize-leaves-a-clipped-ui) needed to locate the remaining mismatch.
|
||||
|
||||
## Legacy operating-system version query
|
||||
|
||||
```sh
|
||||
python3 build/runtime/tools/build-riot-carboncore-runtime.py
|
||||
```
|
||||
|
||||
After installing and activating CarbonCore, run the independent `build/riot-gestalt-version-check` through Darling with the normal framework/library overrides. Expected on the current kernel: `GESTALT_VERSION product=14.7 version=14.7.0 packed=0x1470 architecture=10 pass=1`. It compares the separate version selectors against `kern.osproductversion`, checks packed BCD, confirms architecture remains a separate result, and covers null outputs and unknown selectors. The previous implementation returned 10 for every version component and the packed selector. The probe does not launch or contact Riot. Passing it establishes the API correction, not Vanguard compatibility.
|
||||
|
||||
## Standalone guest probes
|
||||
|
||||
Build and install the base/runtime first. Native probes are built by the incremental runtime scripts. With the default guest username, run a probe like this (replace `me` and the host checkout path):
|
||||
|
||||
@@ -62,6 +62,63 @@ LaunchServices dereferenced a nullable error-output pointer in six paths. The pa
|
||||
|
||||
LaunchServices now opens `http`, `https` and `mailto` links on the Linux desktop itself. It loads the host's `libsystemd.so.0` and asks `xdg-desktop-portal` (`org.freedesktop.portal.OpenURI`) on the user session bus to open the link, so your default browser starts outside Darling and survives `darling shutdown`. Without a portal, it starts `xdg-open` in a transient systemd user unit instead. It also reports a handler for these schemes, since Electron checks for one before opening a link. Other schemes, control characters and URLs over 4096 bytes are rejected. If a link still does nothing, check the client's stderr for a `LaunchServices:` line and that `busctl --user status org.freedesktop.portal.Desktop` works on the host. Both LaunchServices and AppKit must be rebuilt. The hand-off passed the host-side D-Bus regression and opened the host browser from a guest through both `open(1)` and `NSWorkspace`; a link clicked in the Riot client is not yet confirmed. The null-pointer fix does not explain every unrelated button crash.
|
||||
|
||||
## Language dropdown closes Riot, or client resize leaves a clipped UI
|
||||
|
||||
The [report in issue #1](https://github.com/lucannez64/darling-lol/issues/1#issuecomment-6194498757) contains an Electron renderer abort with `Symbol not found: _CTFontDescriptorCreateMatchingFontDescriptors`. CoreText now exports font-descriptor matching and localized-attribute lookup, and enumerates installed font families through fontconfig instead of returning a null stub. Localized lookup currently falls back to canonical font names. The standalone font-list check exercises Chromium's sequence, including mandatory family matching and retained results.
|
||||
|
||||
AppKit also left backing-layer geometry at the old size until a coordinate conversion occurred. It now updates that geometry during frame/bounds changes, and invalidates parent transforms before child resize callbacks. Native parent geometry is updated before resizing child windows, whose Y positions depend on the parent's current height. Standalone regressions reproduce both stale-size defects and pass with the corrections. A follow-up test confirmed that the language dropdown is fixed, but League still displays a 1280×720 image inside a 1600×900 window. The geometry regressions alone do not establish a fix for that remaining resize failure.
|
||||
|
||||
Rebuild and install the runtime using the [update instructions](SETUP.md#updating-an-existing-runtime), with the game and both clients closed. CoreText is now included in the GPU/runtime installer alongside AppKit; existing installations need this new override too. Until then, a locale can be selected at launch, for example `RCLOL_REGION=BR RCLOL_LOCALE=pt_BR ./scripts/run.sh`.
|
||||
|
||||
Live inspection subsequently confirmed a 1600×900 outer League window with both its CoreAnimation child and presentation target still at 1280×720. `NSThemeFrame` selected the last non-menu/toolbar child as the content view. A standalone reproduction showed that an overlay added after the real content received the resize instead. Frame layout now identifies the window's actual content owner (including a containing wrapper), and applies ordinary autoresizing masks to other decorations. A hidden-window regression reproduces the old behavior with an overlay sibling and passes after the fix. The user retested with this build loaded; League still failed to resize. This correction therefore does not resolve the remaining client failure.
|
||||
|
||||
The subsequent file trace showed the browser view reaching the new frame size without a renderer resize, and a later shrink left `RenderWidgetHostViewCocoa` at 1600×900 inside 1280×720 parents. Darling's `NSView setFrame:` directly updated geometry without dispatching `setFrameSize:`. [Chromium's Cocoa implementation](https://chromium.googlesource.com/chromium/src/+/114a1ef9e848ccebec516681bcf1786f85b5cbd6/content/browser/renderer_host/render_widget_host_view_mac.mm#2273) explicitly relies on this dispatch to notify the renderer. AppKit now calls the component setters for changed origins/sizes, with a private geometry updater to avoid recursion. A standalone subclass regression failed before this correction (one callback from four size changes) and passes after it (four callbacks, including parent autoresizing in both directions). The user retested with this AppKit build loaded and still saw clipping. Passive inspection then showed the native CoreAnimation child and a published frame at 1600×900, with the presentation target remaining at 1280×720.
|
||||
|
||||
The X11 presentation selector also retained a software publisher across popup updates even after the window outgrew its old presentation target. If that publisher switched to a small popup and a different publisher supplied the resized main frame, the selector kept following the popup slot and never resized the presentation child. It now retains that owner only while the old presentation dimensions still match a native target. A two-publisher standalone pixel regression reproduces the black enlarged area on the old backend; the new backend passes 1280×720 → 1600×900 → 1024×576 → 1280×720 with and without the shared-memory transport. After installing this backend locally, the user confirmed that League window resizing works (2026-10-15).
|
||||
|
||||
For the AppKit and X11 corrections, exit the game and both clients manually, then use the small update instead of rebuilding the entire runtime:
|
||||
|
||||
```sh
|
||||
python3 scripts/configure.py
|
||||
python3 build/runtime/tools/build-riot-appkit-runtime.py
|
||||
python3 build/runtime/tools/build-riot-x11-runtime.py
|
||||
darling shutdown
|
||||
sh build/runtime/tools/install-riot-appkit-runtime.sh
|
||||
sh scripts/run.sh
|
||||
```
|
||||
|
||||
The installer requires the existing per-user AppKit overlay, saves a checksum-named backup under `build/appkit-runtime-backups`, and atomically replaces each binary, including the paired X11 backend. It does not stop processes or change the system SDK. After launch, change League between 1280×720 and 1600×900 and verify both the rendered extent and click alignment.
|
||||
|
||||
The installer previously preferred an existing `build/riot-QuartzCore` over its newly built `build/m336-QuartzCore`. It now installs the artifact it just rebuilt, and that builder recompiles all patched compositor and Metal presentation objects. This avoids silently installing an older optional probe build.
|
||||
|
||||
If resize clipping recurs, launch with size-only runtime tracing and resize the client manually:
|
||||
|
||||
```sh
|
||||
mkdir -p build
|
||||
env DARLING_UI_GEOMETRY_TRACE=1 sh scripts/run.sh 2>&1 \
|
||||
| rg --line-buffered '^UI_GEOMETRY ' | tee build/ui-geometry.log
|
||||
```
|
||||
|
||||
Change from 1280×720 to 1600×900 and leave the client open at the broken size. AppKit also writes a bounded window/view hierarchy to the guest `/tmp/darling-ui-geometry.log` (host `~/.darling/private/tmp/darling-ui-geometry.log`). Read that file as well as `build/ui-geometry.log`: League redirects stderr, so the terminal capture alone can omit all of its resize events. The traces record window/view classes, identities, dimensions and autoresizing masks, layer scale and IOSurface dimensions at size changes. Tracing is disabled on ordinary launches. It uses the runtime's own geometry setters and surface publisher, with no debugger, client API access or input automation.
|
||||
|
||||
The practice-tool exit in the same report remains unresolved: the supplied League client log records the game starting and exiting about two seconds later, but contains no game-process crash reason. These font and resize fixes do not establish a fix for that exit. Further diagnosis needs the game's own log/crash report or stderr from the affected machine.
|
||||
|
||||
## Client reports macOS 10.10 and VAN -101
|
||||
|
||||
The legacy CarbonCore `Gestalt` implementation read a Darwin kernel release as though it were a macOS product version, then fell through into `gestaltSysArchitecture`, overwriting every result with `gestaltIntel` (10). The standalone probe reproduced `gestalt=10.10.10` even though `kern.osproductversion` was already `14.7`. Version selectors now read that existing product version, return before the architecture case, initialize missing patch versions to zero and implement the documented packed-BCD limits. Null outputs and unknown selectors return errors.
|
||||
|
||||
After installing this correction and restarting locally, the client reported macOS 14.7 and the user confirmed that Play became available. Later launches failed again, including a launch without `DARLING_UI_GEOMETRY_TRACE`. The running client was verified to have the corrected CarbonCore binary loaded. Both successful and failed sessions reported macOS 14.7; successful sessions logged `MvgState: 0`, while failed sessions logged `MvgState: 5`, despite `MvgInit` and `MvgRegisterLogin` returning zero in both. These state values are observations, not a diagnosis of their undocumented meaning. The version correction is therefore insufficient to resolve VAN -101, and tracing is not required to reproduce the failure. Entering a match remains unverified. [Riot describes VAN -101](https://support.riotgames.com/en-us/riot/performance/error-van--101) as an unsupported system configuration and recommends a supported operating system or a support ticket with logs. No verified Darling compatibility fix for this failure is available in this snapshot. A temporary test rollback of commit `ac4a832` restores `proc_listpids` returning `ENOTSUP`; it was followed by both a successful launch and another VAN failure, so it has not established that commit as the cause. Tracing was enabled on the latter launch; its contribution remains unproven.
|
||||
|
||||
Build the small update with `python3 build/runtime/tools/build-riot-carboncore-runtime.py`. After manually exiting the game and both clients:
|
||||
|
||||
```sh
|
||||
darling shutdown
|
||||
sh build/runtime/tools/install-riot-carboncore-runtime.sh
|
||||
sh scripts/run.sh
|
||||
```
|
||||
|
||||
The installer adds a CarbonCore framework override and the matching absolute CoreServices subframework binary in the guest prefix, with checksum-named backups in `build/carboncore-runtime-backups`. It does not modify the SDK or restart processes. Both forms are needed because framework lookup and explicit subframework loading can take different paths. Ordinary full runtime installation includes this update too.
|
||||
|
||||
## `LOLSIGFAIL … addr=0x143` every 10 seconds
|
||||
|
||||
`iokitd` crashed in host glibc's `pthread_mutex_lock` and launchd restarted it every 10 seconds. It called `eglGetDisplay()` with an Xlib display, so Mesa picked the platform from `EGL_PLATFORM`. Wayland sessions often set that to `wayland`, and the first `darling` command passes its environment to every guest service, including `iokitd`. `scripts/run.sh` sets `EGL_PLATFORM=x11` and was unaffected, but `darling shell` from a Wayland terminal (including the one in `scripts/install-runtime.sh`) started the loop. `iokitd` now requests the X11 platform explicitly. The fix is part of the base install (`sudo cmake --install`); until then, start Darling with `EGL_PLATFORM=x11`.
|
||||
|
||||
+430
-58
@@ -1271,10 +1271,42 @@ index 9177a986..9c3c5ca3 100644
|
||||
|
||||
@end
|
||||
diff --git a/AppKit/NSThemeFrame.m b/AppKit/NSThemeFrame.m
|
||||
index 0ec827c0..6f780225 100644
|
||||
index 0ec827c0..a24cd9f5 100644
|
||||
--- a/AppKit/NSThemeFrame.m
|
||||
+++ b/AppKit/NSThemeFrame.m
|
||||
@@ -133,8 +133,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
@@ -85,7 +85,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
- (void) resizeSubviewsWithOldSize: (NSSize) oldSize {
|
||||
NSView *menuView = nil;
|
||||
NSToolbarView *toolbarView = nil;
|
||||
- NSView *contentView = nil;
|
||||
+ /* Browser windows can add overlay/titlebar siblings after their content.
|
||||
+ * Identify the window's actual content owner rather than choosing the
|
||||
+ * last ordinary subview. Full-size content wrappers can own it indirectly. */
|
||||
+ NSView *contentView = [[self window] contentView];
|
||||
+ while (contentView && [contentView superview] && [contentView superview] != self)
|
||||
+ contentView = [contentView superview];
|
||||
+ if ([contentView superview] != self)
|
||||
+ contentView = nil;
|
||||
|
||||
// tile the subviews, when/if we add titlebars and such do it here
|
||||
for (NSView *view in _subviews) {
|
||||
@@ -93,10 +100,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
menuView = view;
|
||||
else if ([view isKindOfClass: [NSToolbarView class]])
|
||||
toolbarView = (NSToolbarView *) view;
|
||||
- else
|
||||
- contentView = view;
|
||||
}
|
||||
|
||||
+ // Other decorations still follow their autoresizing masks.
|
||||
+ for (NSView *view in [[_subviews copy] autorelease])
|
||||
+ if (view != contentView && view != menuView && view != toolbarView)
|
||||
+ [view resizeWithOldSuperviewSize: oldSize];
|
||||
+
|
||||
// subtracts menu height but not toolbar height
|
||||
NSRect contentFrame = [[[self window] class]
|
||||
contentRectForFrameRect: [self bounds]
|
||||
@@ -133,8 +143,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
}
|
||||
|
||||
- (void) mouseDown: (NSEvent *) event {
|
||||
@@ -1300,19 +1332,31 @@ index c3f5d056..dbd93174 100644
|
||||
@"NSTouchBarItemIdentifierCharacterPicker";
|
||||
|
||||
diff --git a/AppKit/NSView.m b/AppKit/NSView.m
|
||||
index 8ac2bbdc..7486ebf5 100644
|
||||
index 8ac2bbdc..08197fbc 100644
|
||||
--- a/AppKit/NSView.m
|
||||
+++ b/AppKit/NSView.m
|
||||
@@ -46,6 +46,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
@@ -46,6 +46,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
#import <QuartzCore/CALayerContext.h>
|
||||
#import <QuartzCore/CATransaction.h>
|
||||
#import <AppKit/NSLayoutConstraint.h>
|
||||
+#import <AppKit/NSTextInput.h>
|
||||
+#import <objc/runtime.h>
|
||||
+#include "NSGeometryTrace.h"
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
@class IBMetricsTable;
|
||||
|
||||
@@ -955,6 +957,54 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
@@ -66,6 +72,7 @@ const NSViewFullScreenModeOptionKey NSFullScreenModeApplicationPresentationOptio
|
||||
- (CGAffineTransform) transformToWindow;
|
||||
- (CGAffineTransform) transformToLayer;
|
||||
- (void) _trackingAreasChanged;
|
||||
+- (void) _darlingSetFrame: (NSRect) frame;
|
||||
@end
|
||||
|
||||
@implementation NSView
|
||||
@@ -955,6 +962,54 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
CGPointApplyAffineTransform(point, toWindow), fromWindow);
|
||||
}
|
||||
|
||||
@@ -1367,7 +1411,77 @@ index 8ac2bbdc..7486ebf5 100644
|
||||
- (NSSize) convertSize: (NSSize) size fromView: (NSView *) viewOrNil {
|
||||
NSView *fromView =
|
||||
(viewOrNil != nil) ? viewOrNil : [[self window] _backgroundView];
|
||||
@@ -1254,7 +1304,11 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
@@ -1029,6 +1084,16 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
}
|
||||
|
||||
- (void) setFrame: (NSRect) frame {
|
||||
+ /* AppKit dispatches through the component setters. Subclasses use
|
||||
+ * setFrameSize: to notify their renderer even when callers set a full
|
||||
+ * frame (including autoresizing through resizeWithOldSuperviewSize:). */
|
||||
+ if (!NSEqualPoints(_frame.origin, frame.origin))
|
||||
+ [self setFrameOrigin: frame.origin];
|
||||
+ if (!NSEqualSizes(_frame.size, frame.size))
|
||||
+ [self setFrameSize: frame.size];
|
||||
+}
|
||||
+
|
||||
+- (void) _darlingSetFrame: (NSRect) frame {
|
||||
// Cocoa does not post the notification if the frames are equal
|
||||
// Possible that resizeSubviewsWithOldSize is not called if the sizes are
|
||||
// equal
|
||||
@@ -1052,6 +1117,12 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
}
|
||||
_frame = frame;
|
||||
|
||||
+ /* Resize callbacks can convert child frames to window coordinates. They
|
||||
+ * must see the new parent transform, and compositor submissions must see
|
||||
+ * the new layer bounds even before the next coordinate conversion. */
|
||||
+ invalidateTransform(self);
|
||||
+ configureLayerGeometry(self);
|
||||
+
|
||||
[_window invalidateCursorRectsForView: self]; // this also invalidates
|
||||
// tracking areas
|
||||
|
||||
@@ -1068,6 +1139,14 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
|
||||
invalidateTransform(self);
|
||||
|
||||
+ if (getenv("DARLING_UI_GEOMETRY_TRACE") &&
|
||||
+ (_frame.size.width >= 256 || _frame.size.height >= 256))
|
||||
+ DarlingGeometryTrace("UI_GEOMETRY view pid=%d class=%s parent=%s frame=%.0fx%.0f bounds=%.0fx%.0f mask=%lu autoresizes=%d\n",
|
||||
+ getpid(), class_getName([self class]),
|
||||
+ _superview ? class_getName([_superview class]) : "none",
|
||||
+ _frame.size.width, _frame.size.height, _bounds.size.width, _bounds.size.height,
|
||||
+ (unsigned long)_autoresizingMask, _autoresizesSubviews);
|
||||
+
|
||||
if (_postsNotificationOnFrameChange)
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
postNotificationName: NSViewFrameDidChangeNotification
|
||||
@@ -1078,14 +1157,14 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
NSRect frame = _frame;
|
||||
|
||||
frame.size = size;
|
||||
- [self setFrame: frame];
|
||||
+ [self _darlingSetFrame: frame];
|
||||
}
|
||||
|
||||
- (void) setFrameOrigin: (NSPoint) origin {
|
||||
NSRect frame = [self frame];
|
||||
|
||||
frame.origin = origin;
|
||||
- [self setFrame: frame];
|
||||
+ [self _darlingSetFrame: frame];
|
||||
}
|
||||
|
||||
- (void) setFrameRotation: (CGFloat) angle {
|
||||
@@ -1100,6 +1179,7 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
if (!NSEqualRects(bounds, _bounds)) {
|
||||
_bounds = bounds;
|
||||
invalidateTransform(self);
|
||||
+ configureLayerGeometry(self);
|
||||
|
||||
[_window invalidateCursorRectsForView: self]; // this also invalidates
|
||||
// tracking areas
|
||||
@@ -1254,7 +1334,11 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
(NSComparisonResult (*)(id, id, void *)) compareFunction
|
||||
context: (void *) context
|
||||
{
|
||||
@@ -1380,7 +1494,7 @@ index 8ac2bbdc..7486ebf5 100644
|
||||
}
|
||||
|
||||
- (void) didAddSubview: (NSView *) subview {
|
||||
@@ -1511,8 +1565,16 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
@@ -1511,8 +1595,16 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
}
|
||||
|
||||
- (NSTextInputContext *) inputContext {
|
||||
@@ -1399,7 +1513,7 @@ index 8ac2bbdc..7486ebf5 100644
|
||||
}
|
||||
|
||||
- (void) registerForDraggedTypes: (NSArray *) types {
|
||||
@@ -1819,15 +1881,21 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
@@ -1819,15 +1911,21 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
|
||||
- (void) _createLayerContextIfNeeded {
|
||||
if ([_superview layer] == nil) {
|
||||
@@ -1423,7 +1537,7 @@ index 8ac2bbdc..7486ebf5 100644
|
||||
[[_superview layer] addSublayer: _layer];
|
||||
[self _createLayerContextIfNeeded];
|
||||
}
|
||||
@@ -1905,6 +1973,7 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
@@ -1905,6 +2003,7 @@ static inline void buildTransformsIfNeeded(NSView *self) {
|
||||
[[_superview layer] replaceSublayer: _layer with: value];
|
||||
[_layer release];
|
||||
_layer = value;
|
||||
@@ -1432,14 +1546,15 @@ index 8ac2bbdc..7486ebf5 100644
|
||||
|
||||
[_subviews
|
||||
diff --git a/AppKit/NSWindow.m b/AppKit/NSWindow.m
|
||||
index d545120a..db2c12d9 100644
|
||||
index d545120a..b2845478 100644
|
||||
--- a/AppKit/NSWindow.m
|
||||
+++ b/AppKit/NSWindow.m
|
||||
@@ -45,6 +45,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
@@ -45,6 +45,21 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
#import <AppKit/NSWindowAnimationContext.h>
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
#import <CoreGraphics/CGWindow.h>
|
||||
+#import <objc/runtime.h>
|
||||
+#include "NSGeometryTrace.h"
|
||||
+#include <unistd.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
@@ -1456,7 +1571,7 @@ index d545120a..db2c12d9 100644
|
||||
|
||||
const NSNotificationName NSWindowDidBecomeKeyNotification =
|
||||
@"NSWindowDidBecomeKeyNotification";
|
||||
@@ -204,6 +218,25 @@ NSInteger NSBitsPerPixelFromDepth(NSWindowDepth depth) {
|
||||
@@ -204,6 +219,25 @@ NSInteger NSBitsPerPixelFromDepth(NSWindowDepth depth) {
|
||||
|
||||
@end
|
||||
|
||||
@@ -1482,7 +1597,7 @@ index d545120a..db2c12d9 100644
|
||||
@implementation NSWindow
|
||||
|
||||
@synthesize identifier = _identifier;
|
||||
@@ -218,7 +251,8 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -218,7 +252,8 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
/* This method is Cococtron specific and can be override by subclasses, do not
|
||||
* change method name */
|
||||
+ (BOOL) hasMainMenuForStyleMask: (NSWindowStyleMask) styleMask {
|
||||
@@ -1492,7 +1607,7 @@ index d545120a..db2c12d9 100644
|
||||
}
|
||||
|
||||
/* This method is Cococtron specific and can be override by subclasses, do not
|
||||
@@ -318,6 +352,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -318,6 +353,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
[NSApplication sharedApplication];
|
||||
}
|
||||
_styleMask = styleMask;
|
||||
@@ -1500,7 +1615,7 @@ index d545120a..db2c12d9 100644
|
||||
_backingType = backing;
|
||||
_isDeferred = defer;
|
||||
|
||||
@@ -351,7 +386,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -351,7 +387,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
[_backgroundView _setWindow: self];
|
||||
[_backgroundView setNextResponder: self];
|
||||
|
||||
@@ -1509,7 +1624,7 @@ index d545120a..db2c12d9 100644
|
||||
_contentView = [[NSView alloc] initWithFrame: contentViewFrame];
|
||||
[_contentView setAutoresizesSubviews: YES];
|
||||
[_contentView
|
||||
@@ -399,6 +434,8 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -399,6 +435,8 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
}
|
||||
|
||||
- (void) dealloc {
|
||||
@@ -1518,7 +1633,51 @@ index d545120a..db2c12d9 100644
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
||||
[_childWindows release];
|
||||
[_title release];
|
||||
@@ -1025,7 +1062,34 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -934,6 +972,22 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
return _animationContext;
|
||||
}
|
||||
|
||||
+/* Dump geometry only, including children which did not receive a resize.
|
||||
+ * The node/depth bounds keep malformed or unexpectedly large trees bounded. */
|
||||
+static void traceGeometryTree(NSView *view, unsigned depth, unsigned *remaining) {
|
||||
+ if (!view || depth > 12 || !*remaining)
|
||||
+ return;
|
||||
+ --*remaining;
|
||||
+ NSRect frame = [view frame], bounds = [view bounds];
|
||||
+ DarlingGeometryTrace("UI_GEOMETRY tree pid=%d depth=%u view=%p class=%s parent=%p frame=%.0f,%.0f,%.0fx%.0f bounds=%.0f,%.0f,%.0fx%.0f mask=%lu autoresizes=%d layer=%d\n",
|
||||
+ getpid(), depth, view, class_getName([view class]), [view superview],
|
||||
+ frame.origin.x, frame.origin.y, frame.size.width, frame.size.height,
|
||||
+ bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height,
|
||||
+ (unsigned long)[view autoresizingMask], [view autoresizesSubviews], [view wantsLayer]);
|
||||
+ for (NSView *child in [view subviews])
|
||||
+ traceGeometryTree(child, depth + 1, remaining);
|
||||
+}
|
||||
+
|
||||
- (void) setFrame: (NSRect) newFrame
|
||||
display: (BOOL) display
|
||||
animate: (BOOL) animate
|
||||
@@ -944,8 +998,19 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
_frame = newFrame;
|
||||
_makeSureIsOnAScreen = YES;
|
||||
|
||||
- [_backgroundView setFrameSize: _frame.size];
|
||||
+ /* Native child windows convert their Y origin using the platform
|
||||
+ * window's height. Update it before laying out/resizing those children. */
|
||||
[_platformWindow setFrame: _frame];
|
||||
+ [_backgroundView setFrameSize: _frame.size];
|
||||
+
|
||||
+ if (didSize && getenv("DARLING_UI_GEOMETRY_TRACE")) {
|
||||
+ NSSize contentSize = [_contentView frame].size;
|
||||
+ DarlingGeometryTrace("UI_GEOMETRY window pid=%d class=%s frame=%.0fx%.0f content=%.0fx%.0f style=%lu window=%p contentView=%p\n",
|
||||
+ getpid(), class_getName([self class]), _frame.size.width, _frame.size.height,
|
||||
+ contentSize.width, contentSize.height, (unsigned long)_styleMask, self, [self contentView]);
|
||||
+ unsigned remaining = 128;
|
||||
+ traceGeometryTree(_backgroundView, 0, &remaining);
|
||||
+ }
|
||||
|
||||
if (didSize) {
|
||||
[self resetCursorRects];
|
||||
@@ -1025,7 +1090,34 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
}
|
||||
|
||||
- (void) setMovable: (BOOL) movable {
|
||||
@@ -1554,7 +1713,7 @@ index d545120a..db2c12d9 100644
|
||||
}
|
||||
|
||||
- (void) setBackingType: (NSBackingStoreType) value {
|
||||
@@ -1234,6 +1298,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -1234,6 +1326,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
|
||||
- (void) setIgnoresMouseEvents: (BOOL) value {
|
||||
_ignoresMouseEvents = value;
|
||||
@@ -1562,7 +1721,7 @@ index d545120a..db2c12d9 100644
|
||||
}
|
||||
|
||||
- (void) setAspectRatio: (NSSize) value {
|
||||
@@ -1413,8 +1478,14 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -1413,8 +1506,14 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
}
|
||||
|
||||
- (NSButton *) standardWindowButton: (NSWindowButton) value {
|
||||
@@ -1579,7 +1738,7 @@ index d545120a..db2c12d9 100644
|
||||
}
|
||||
|
||||
- (NSButtonCell *) defaultButtonCell {
|
||||
@@ -1425,6 +1496,17 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -1425,6 +1524,17 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
return [_sheetContext sheet];
|
||||
}
|
||||
|
||||
@@ -1597,7 +1756,7 @@ index d545120a..db2c12d9 100644
|
||||
- (id) windowController {
|
||||
return _windowController;
|
||||
}
|
||||
@@ -1511,10 +1593,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -1511,10 +1621,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
return [_platformWindow isMiniaturized];
|
||||
}
|
||||
|
||||
@@ -1609,7 +1768,7 @@ index d545120a..db2c12d9 100644
|
||||
|
||||
- (BOOL) inLiveResize {
|
||||
return _isInLiveResize;
|
||||
@@ -1561,6 +1640,117 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -1561,6 +1668,117 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
return point;
|
||||
}
|
||||
|
||||
@@ -1727,7 +1886,7 @@ index d545120a..db2c12d9 100644
|
||||
- (NSRect) frameRectForContentRect: (NSRect) contentRect {
|
||||
// hasMainMenu is an instance method so we can't just use the class method
|
||||
// frameRectForContentRect:styleMask:
|
||||
@@ -1580,6 +1761,10 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -1580,6 +1798,10 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
}
|
||||
|
||||
- (NSRect) contentRectForFrameRect: (NSRect) frameRect {
|
||||
@@ -1738,7 +1897,7 @@ index d545120a..db2c12d9 100644
|
||||
NSRect result = [[NSDisplay currentDisplay] insetRect: frameRect
|
||||
forNativeWindowBorderWithStyle: [self styleMask]];
|
||||
|
||||
@@ -2155,6 +2340,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -2155,6 +2377,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
- (void) orderWindow: (NSWindowOrderingMode) place
|
||||
relativeTo: (NSInteger) relativeTo
|
||||
{
|
||||
@@ -1746,7 +1905,7 @@ index d545120a..db2c12d9 100644
|
||||
// The move notifications are sent under unknown conditions around
|
||||
// orderFront: in the Apple AppKit, we do them all the time here until it's
|
||||
// figured out. I suspect it is a side effect of off-screen windows being at
|
||||
@@ -2208,6 +2394,8 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -2208,6 +2431,8 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1755,7 +1914,7 @@ index d545120a..db2c12d9 100644
|
||||
[self postNotificationName: NSWindowDidMoveNotification];
|
||||
}
|
||||
|
||||
@@ -2257,6 +2445,12 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -2257,6 +2482,12 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
}
|
||||
|
||||
- (void) sendEvent: (NSEvent *) event {
|
||||
@@ -1768,7 +1927,7 @@ index d545120a..db2c12d9 100644
|
||||
// Some events can cause our window to be destroyed
|
||||
// So make sure self lives at least through this current run loop...
|
||||
[[self retain] autorelease];
|
||||
@@ -2300,6 +2494,10 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -2300,6 +2531,10 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
|
||||
case NSLeftMouseDown: {
|
||||
NSView *view = [_backgroundView hitTest: [event locationInWindow]];
|
||||
@@ -1779,7 +1938,7 @@ index d545120a..db2c12d9 100644
|
||||
|
||||
if ([view acceptsFirstResponder]) {
|
||||
if ([view needsPanelToBecomeKey]) {
|
||||
@@ -2307,6 +2505,27 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -2307,6 +2542,27 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1807,7 +1966,7 @@ index d545120a..db2c12d9 100644
|
||||
// Event goes to view, not first responder.
|
||||
[view mouseDown: event];
|
||||
_mouseDownLocationInWindow = [event locationInWindow];
|
||||
@@ -2330,6 +2549,31 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -2330,6 +2586,31 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
_mouseDownLocationInWindow = NSMakePoint(NAN, NAN);
|
||||
break;
|
||||
|
||||
@@ -1839,7 +1998,7 @@ index d545120a..db2c12d9 100644
|
||||
case NSMouseMoved: {
|
||||
NSView *hit = [_backgroundView hitTest: [event locationInWindow]];
|
||||
|
||||
@@ -2536,6 +2780,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -2536,6 +2817,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
} else {
|
||||
[[self platformWindow] hideWindow];
|
||||
}
|
||||
@@ -1847,7 +2006,21 @@ index d545120a..db2c12d9 100644
|
||||
}
|
||||
|
||||
- (void) orderFront: (id) sender {
|
||||
@@ -3260,8 +3505,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -3064,6 +3346,13 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
if (didSize) {
|
||||
// Don't redraw everything unless we really have to.
|
||||
[_backgroundView setFrameSize: _frame.size];
|
||||
+ if (getenv("DARLING_UI_GEOMETRY_TRACE")) {
|
||||
+ DarlingGeometryTrace("UI_GEOMETRY native_window pid=%d window=%p contentView=%p frame=%.0fx%.0f\n",
|
||||
+ getpid(), self, [self contentView],
|
||||
+ _frame.size.width, _frame.size.height);
|
||||
+ unsigned remaining = 128;
|
||||
+ traceGeometryTree(_backgroundView, 0, &remaining);
|
||||
+ }
|
||||
[_backgroundView setNeedsDisplay: YES];
|
||||
[self resetCursorRects];
|
||||
[self saveFrameUsingName: _autosaveFrameName];
|
||||
@@ -3260,8 +3549,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
mouseWasInside && !mouseIsInside) {
|
||||
[exited addObject: area];
|
||||
}
|
||||
@@ -1857,7 +2030,7 @@ index d545120a..db2c12d9 100644
|
||||
[moved addObject: area];
|
||||
}
|
||||
if (options & NSTrackingCursorUpdate && !mouseWasInside &&
|
||||
@@ -3459,7 +3703,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
@@ -3459,7 +3747,7 @@ static BOOL _allowsAutomaticWindowTabbing;
|
||||
}
|
||||
|
||||
- (CGSubWindow *) _createSubWindowWithFrame: (CGRect) frame {
|
||||
@@ -2957,7 +3130,7 @@ index bfe3839a..2521ffd5 100644
|
||||
- (void) frameChanged;
|
||||
- (void) setLastKnownCursorPosition: (CGPoint) point;
|
||||
diff --git a/AppKit/X11.backend/X11Window.m b/AppKit/X11.backend/X11Window.m
|
||||
index f4925b66..8553a8b4 100644
|
||||
index f4925b66..67b084a0 100644
|
||||
--- a/AppKit/X11.backend/X11Window.m
|
||||
+++ b/AppKit/X11.backend/X11Window.m
|
||||
@@ -38,6 +38,34 @@
|
||||
@@ -3114,7 +3287,7 @@ index f4925b66..8553a8b4 100644
|
||||
[_context release];
|
||||
_context = nil;
|
||||
|
||||
@@ -421,6 +499,379 @@ static NSData *makeWindowIcon() {
|
||||
@@ -421,6 +499,388 @@ static NSData *makeWindowIcon() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3280,9 +3453,18 @@ index f4925b66..8553a8b4 100644
|
||||
+ closedir(dir);
|
||||
+ }
|
||||
+
|
||||
+ /* Keep the software compositor owner across its other window updates.
|
||||
+ * Otherwise a temporary size mismatch selects stale browser readback. */
|
||||
+ if (_remoteFrameSoftwarePublisher && _remoteFrameMapping && !bestSoftware) {
|
||||
+ /* Keep a software owner across popup updates while the presented size
|
||||
+ * still belongs to this window. After a real resize, retaining that owner
|
||||
+ * can strand us on its popup slot even though a matching readback frame
|
||||
+ * is ready from another publisher. Let normal candidate selection make
|
||||
+ * that handoff when the old presentation no longer matches a target. */
|
||||
+ BOOL presentationMatchesTarget = NO;
|
||||
+ for (unsigned i = 0; i < frameTargetCount; ++i)
|
||||
+ if (_remoteFrameWidth == (unsigned)frameTargets[i].width &&
|
||||
+ _remoteFrameHeight == (unsigned)frameTargets[i].height)
|
||||
+ presentationMatchesTarget = YES;
|
||||
+ if (_remoteFrameSoftwarePublisher && _remoteFrameMapping && !bestSoftware &&
|
||||
+ presentationMatchesTarget) {
|
||||
+ const char *pidText = strrchr(_remoteFrameMappingPath, '-');
|
||||
+ int publisher = pidText ? atoi(pidText + 1) : 0;
|
||||
+ if (publisher > 0 && (kill(publisher, 0) == 0 || errno != ESRCH)) {
|
||||
@@ -3494,7 +3676,7 @@ index f4925b66..8553a8b4 100644
|
||||
- (Window) windowHandle {
|
||||
return _window;
|
||||
}
|
||||
@@ -478,6 +929,15 @@ static NSData *makeWindowIcon() {
|
||||
@@ -478,6 +938,15 @@ static NSData *makeWindowIcon() {
|
||||
frame.size.width, frame.size.height);
|
||||
[self invalidateContextWithNewSize: frame.size];
|
||||
_frame = frame;
|
||||
@@ -3510,7 +3692,7 @@ index f4925b66..8553a8b4 100644
|
||||
}
|
||||
|
||||
- (void) setHasShadow: (BOOL) value {
|
||||
@@ -559,7 +1019,29 @@ static NSData *makeWindowIcon() {
|
||||
@@ -559,7 +1028,29 @@ static NSData *makeWindowIcon() {
|
||||
XRaiseWindow(_display, _window);
|
||||
}
|
||||
|
||||
@@ -3540,7 +3722,7 @@ index f4925b66..8553a8b4 100644
|
||||
Atom wmState = XInternAtom(_display, "_NET_WM_STATE", FALSE);
|
||||
Atom hiddenState = XInternAtom(_display, "_NET_WM_STATE_HIDDEN", FALSE);
|
||||
|
||||
@@ -615,6 +1097,12 @@ static NSData *makeWindowIcon() {
|
||||
@@ -615,6 +1106,12 @@ static NSData *makeWindowIcon() {
|
||||
}
|
||||
|
||||
- (void) openGLFlushBuffer {
|
||||
@@ -3553,7 +3735,7 @@ index f4925b66..8553a8b4 100644
|
||||
CGLError error;
|
||||
|
||||
CGLContextObj prevContext = CGLGetCurrentContext();
|
||||
@@ -666,6 +1154,7 @@ static int ignoreBadWindow(Display *display, XErrorEvent *errorEvent) {
|
||||
@@ -666,6 +1163,7 @@ static int ignoreBadWindow(Display *display, XErrorEvent *errorEvent) {
|
||||
}
|
||||
|
||||
- (void) frameChanged {
|
||||
@@ -4587,7 +4769,7 @@ index e1112f40..3a4fa2d6 100644
|
||||
COREGRAPHICS_EXPORT CGImageRef CGWindowListCreateImageFromArray(CGRect screenBounds, CFArrayRef windowArray, CGWindowImageOption imageOption);
|
||||
|
||||
diff --git a/CoreText/CMakeLists.txt b/CoreText/CMakeLists.txt
|
||||
index 1ec11620..08a238ca 100644
|
||||
index 1ec11620..af21f5b3 100644
|
||||
--- a/CoreText/CMakeLists.txt
|
||||
+++ b/CoreText/CMakeLists.txt
|
||||
@@ -28,7 +28,6 @@ set(CoreText_sources
|
||||
@@ -4598,6 +4780,12 @@ index 1ec11620..08a238ca 100644
|
||||
)
|
||||
|
||||
set_source_files_properties(${CoreText_sources} LANGUAGE C)
|
||||
@@ -58,4 +57,5 @@ add_framework(CoreText
|
||||
Onyx2D
|
||||
# native
|
||||
FreeType
|
||||
+ fontconfig
|
||||
)
|
||||
diff --git a/CoreText/CTFont.m b/CoreText/CTFont.m
|
||||
index 94ddabf9..fa018d3d 100644
|
||||
--- a/CoreText/CTFont.m
|
||||
@@ -5236,10 +5424,19 @@ index 94ddabf9..fa018d3d 100644
|
||||
|
||||
CFTypeID CTFontGetTypeID(void)
|
||||
diff --git a/CoreText/CTFontDescriptor.m b/CoreText/CTFontDescriptor.m
|
||||
index 8866ce59..eb8a101c 100644
|
||||
index 8866ce59..62dcf226 100644
|
||||
--- a/CoreText/CTFontDescriptor.m
|
||||
+++ b/CoreText/CTFontDescriptor.m
|
||||
@@ -24,9 +24,23 @@ const CFStringRef kCTFontEnabledAttribute = CFSTR("NSCTFontEnabledAttribute");
|
||||
@@ -1,6 +1,7 @@
|
||||
#import <CoreText/CTFontDescriptor.h>
|
||||
|
||||
-#include <stdio.h>
|
||||
+#import <Foundation/Foundation.h>
|
||||
+#import <Onyx2D/O2Font_freetype.h>
|
||||
|
||||
const CFStringRef kCTFontURLAttribute = CFSTR("NSCTFontFileURLAttribute");
|
||||
const CFStringRef kCTFontNameAttribute = CFSTR("NSFontNameAttribute");
|
||||
@@ -24,9 +25,103 @@ const CFStringRef kCTFontEnabledAttribute = CFSTR("NSCTFontEnabledAttribute");
|
||||
const CFStringRef kCTFontFormatAttribute = CFSTR("NSCTFontFormatAttribute");
|
||||
const CFStringRef kCTFontRegistrationScopeAttribute = CFSTR("NSCTFontRegistrationScopeAttribute");
|
||||
const CFStringRef kCTFontPriorityAttribute = CFSTR("NSCTFontPriorityAttribute");
|
||||
@@ -5264,17 +5461,99 @@ index 8866ce59..eb8a101c 100644
|
||||
+ if (value)
|
||||
+ CFRetain(value);
|
||||
+ return value;
|
||||
+}
|
||||
+
|
||||
+/* Enumerate actual installed faces, rather than returning the query itself.
|
||||
+ * FcFontList does not substitute an unrelated font for a missing family. */
|
||||
+CFArrayRef CTFontDescriptorCreateMatchingFontDescriptors(CTFontDescriptorRef descriptor,
|
||||
+ CFSetRef mandatoryAttributes)
|
||||
+{
|
||||
+ if (!descriptor)
|
||||
+ return NULL;
|
||||
+ NSDictionary *query = (NSDictionary *)descriptor;
|
||||
+ FcPattern *pattern = FcPatternCreate();
|
||||
+ const CFStringRef keys[] = { kCTFontFamilyNameAttribute, kCTFontNameAttribute,
|
||||
+ kCTFontStyleNameAttribute, kCTFontDisplayNameAttribute };
|
||||
+ const char *properties[] = { FC_FAMILY, FC_POSTSCRIPT_NAME, FC_STYLE, FC_FULLNAME };
|
||||
+ for (unsigned i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i) {
|
||||
+ id value = [query objectForKey:(id)keys[i]];
|
||||
+ if ([value isKindOfClass:[NSString class]])
|
||||
+ FcPatternAddString(pattern, properties[i], (const FcChar8 *)[value UTF8String]);
|
||||
+ }
|
||||
+ FcObjectSet *objects = FcObjectSetBuild(FC_FAMILY, FC_POSTSCRIPT_NAME,
|
||||
+ FC_STYLE, FC_FULLNAME, FC_FILE, NULL);
|
||||
+ FcFontSet *fonts = FcFontList(O2FontSharedFontConfig(), pattern, objects);
|
||||
+ CFMutableArrayRef matchesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
|
||||
+ for (int i = 0; fonts && i < fonts->nfont; ++i) {
|
||||
+ NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
|
||||
+ for (unsigned j = 0; j < sizeof(keys) / sizeof(keys[0]); ++j) {
|
||||
+ FcChar8 *text;
|
||||
+ if (FcPatternGetString(fonts->fonts[i], properties[j], 0, &text) == FcResultMatch) {
|
||||
+ NSString *value = [NSString stringWithUTF8String:(const char *)text];
|
||||
+ if (value) [attributes setObject:value forKey:(id)keys[j]];
|
||||
+ }
|
||||
+ }
|
||||
+ FcChar8 *file;
|
||||
+ if (FcPatternGetString(fonts->fonts[i], FC_FILE, 0, &file) == FcResultMatch) {
|
||||
+ NSURL *url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:(const char *)file]];
|
||||
+ if (url) [attributes setObject:url forKey:(id)kCTFontURLAttribute];
|
||||
+ }
|
||||
+ /* Point size is a request, not an installed-face property. */
|
||||
+ id size = [query objectForKey:(id)kCTFontSizeAttribute];
|
||||
+ if (size) [attributes setObject:size forKey:(id)kCTFontSizeAttribute];
|
||||
+ BOOL matches = YES;
|
||||
+ for (id key in (NSSet *)mandatoryAttributes) {
|
||||
+ id expected = [query objectForKey:key];
|
||||
+ if (!expected || ![expected isEqual:[attributes objectForKey:key]]) {
|
||||
+ matches = NO;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (matches) {
|
||||
+ CTFontDescriptorRef match = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)attributes);
|
||||
+ CFArrayAppendValue(matchesArray, match);
|
||||
+ CFRelease(match);
|
||||
+ }
|
||||
+ }
|
||||
+ if (fonts) FcFontSetDestroy(fonts);
|
||||
+ FcObjectSetDestroy(objects);
|
||||
+ FcPatternDestroy(pattern);
|
||||
+ return matchesArray;
|
||||
+}
|
||||
+
|
||||
+CTFontDescriptorRef CTFontDescriptorCreateMatchingFontDescriptor(CTFontDescriptorRef descriptor,
|
||||
+ CFSetRef mandatoryAttributes)
|
||||
+{
|
||||
+ CFArrayRef matches = CTFontDescriptorCreateMatchingFontDescriptors(descriptor, mandatoryAttributes);
|
||||
+ CTFontDescriptorRef result = NULL;
|
||||
+ if (matches) {
|
||||
+ if (CFArrayGetCount(matches))
|
||||
+ result = (CTFontDescriptorRef)CFRetain(CFArrayGetValueAtIndex(matches, 0));
|
||||
+ CFRelease(matches);
|
||||
+ }
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+CFTypeRef CTFontDescriptorCopyLocalizedAttribute(CTFontDescriptorRef descriptor,
|
||||
+ CFStringRef attribute, CFStringRef *language)
|
||||
+{
|
||||
+ /* Fall back to the canonical name when localized font metadata is absent.
|
||||
+ * A NULL language output is valid (Chromium uses it for family names). */
|
||||
+ if (language) *language = NULL;
|
||||
+ return CTFontDescriptorCopyAttribute(descriptor, attribute);
|
||||
}
|
||||
diff --git a/CoreText/CTFontManager.m b/CoreText/CTFontManager.m
|
||||
index 943e1b78..5c295cbf 100644
|
||||
index 943e1b78..049665fb 100644
|
||||
--- a/CoreText/CTFontManager.m
|
||||
+++ b/CoreText/CTFontManager.m
|
||||
@@ -1,17 +1,24 @@
|
||||
@@ -1,23 +1,43 @@
|
||||
#import <CoreText/CTFontManager.h>
|
||||
+#import <CoreText/CTFontDescriptor.h>
|
||||
+#import <Foundation/NSString.h>
|
||||
+#import <Foundation/NSDictionary.h>
|
||||
+#import <Foundation/NSData.h>
|
||||
+#import <Foundation/NSSet.h>
|
||||
+#import <Foundation/NSArray.h>
|
||||
|
||||
const CFStringRef kCTFontManagerRegisteredFontsChangedNotification = CFSTR("CTFontManagerFontChangedNotification");
|
||||
|
||||
@@ -5298,7 +5577,26 @@ index 943e1b78..5c295cbf 100644
|
||||
}
|
||||
|
||||
CFArrayRef CTFontManagerCopyAvailableFontFamilyNames(void)
|
||||
@@ -25,3 +32,118 @@ bool CTFontManagerRegisterFontsForURL(CFURLRef fontURL, CTFontManagerScope scope
|
||||
{
|
||||
- printf("STUB %s\n", __PRETTY_FUNCTION__);
|
||||
- return nil;
|
||||
+ CFDictionaryRef empty = CFDictionaryCreate(NULL, NULL, NULL, 0,
|
||||
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||
+ CTFontDescriptorRef query = CTFontDescriptorCreateWithAttributes(empty);
|
||||
+ CFArrayRef descriptors = CTFontDescriptorCreateMatchingFontDescriptors(query, NULL);
|
||||
+ NSMutableSet *families = [NSMutableSet set];
|
||||
+ for (NSDictionary *descriptor in (NSArray *)descriptors) {
|
||||
+ id family = [descriptor objectForKey:(id)kCTFontFamilyNameAttribute];
|
||||
+ if (family) [families addObject:family];
|
||||
+ }
|
||||
+ CFRelease(query);
|
||||
+ CFRelease(empty);
|
||||
+ if (descriptors) CFRelease(descriptors);
|
||||
+ return (CFArrayRef)[[[families allObjects] sortedArrayUsingSelector:@selector(compare:)] copy];
|
||||
}
|
||||
|
||||
bool CTFontManagerRegisterFontsForURL(CFURLRef fontURL, CTFontManagerScope scope, CFErrorRef * error)
|
||||
@@ -25,3 +45,118 @@ bool CTFontManagerRegisterFontsForURL(CFURLRef fontURL, CTFontManagerScope scope
|
||||
printf("STUB %s\n", __PRETTY_FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
@@ -5575,9 +5873,15 @@ index 33dc18c6..78887dd8 100644
|
||||
|
||||
@end
|
||||
diff --git a/CoreText/include/CoreText/CTFontDescriptor.h b/CoreText/include/CoreText/CTFontDescriptor.h
|
||||
index b2688960..61dfef1a 100644
|
||||
index b2688960..fee68509 100644
|
||||
--- a/CoreText/include/CoreText/CTFontDescriptor.h
|
||||
+++ b/CoreText/include/CoreText/CTFontDescriptor.h
|
||||
@@ -1,4 +1,4 @@
|
||||
-#import <CoreFoundation/CFString.h>
|
||||
+#import <CoreFoundation/CoreFoundation.h>
|
||||
#import <CoreText/CoreTextExport.h>
|
||||
#import <CoreText/CTFontTraits.h>
|
||||
|
||||
@@ -24,6 +24,19 @@ CORETEXT_EXPORT const CFStringRef kCTFontEnabledAttribute;
|
||||
CORETEXT_EXPORT const CFStringRef kCTFontFormatAttribute;
|
||||
CORETEXT_EXPORT const CFStringRef kCTFontRegistrationScopeAttribute;
|
||||
@@ -5598,11 +5902,15 @@ index b2688960..61dfef1a 100644
|
||||
|
||||
CF_IMPLICIT_BRIDGING_ENABLED
|
||||
|
||||
@@ -39,5 +52,6 @@ typedef enum CTFontOrientation : uint32_t {
|
||||
@@ -39,5 +52,10 @@ typedef enum CTFontOrientation : uint32_t {
|
||||
} CTFontOrientation;
|
||||
|
||||
CORETEXT_EXPORT CFTypeRef CTFontDescriptorCopyAttribute(CTFontDescriptorRef descriptor, CFStringRef attribute);
|
||||
+CORETEXT_EXPORT CTFontDescriptorRef CTFontDescriptorCreateWithAttributes(CFDictionaryRef attributes);
|
||||
+
|
||||
+CORETEXT_EXPORT CFArrayRef CTFontDescriptorCreateMatchingFontDescriptors(CTFontDescriptorRef descriptor, CFSetRef mandatoryAttributes);
|
||||
+CORETEXT_EXPORT CTFontDescriptorRef CTFontDescriptorCreateMatchingFontDescriptor(CTFontDescriptorRef descriptor, CFSetRef mandatoryAttributes);
|
||||
+CORETEXT_EXPORT CFTypeRef CTFontDescriptorCopyLocalizedAttribute(CTFontDescriptorRef descriptor, CFStringRef attribute, CFStringRef *language);
|
||||
|
||||
CF_IMPLICIT_BRIDGING_DISABLED
|
||||
diff --git a/CoreText/include/CoreText/KTFont.h b/CoreText/include/CoreText/KTFont.h
|
||||
@@ -5957,10 +6265,10 @@ index 039d8c94..b518c961 100644
|
||||
#import <fontconfig/fontconfig.h>
|
||||
|
||||
diff --git a/QuartzCore/CALayer.m b/QuartzCore/CALayer.m
|
||||
index 5dcac115..7cc63b0b 100644
|
||||
index 5dcac115..5de4f03f 100644
|
||||
--- a/QuartzCore/CALayer.m
|
||||
+++ b/QuartzCore/CALayer.m
|
||||
@@ -1,8 +1,234 @@
|
||||
@@ -1,8 +1,243 @@
|
||||
#import <Foundation/NSDictionary.h>
|
||||
+#import <Foundation/NSInvocation.h>
|
||||
+#import <Foundation/NSMethodSignature.h>
|
||||
@@ -6032,6 +6340,15 @@ index 5dcac115..7cc63b0b 100644
|
||||
+ }
|
||||
+ size_t width = IOSurfaceGetWidth(surface);
|
||||
+ size_t height = IOSurfaceGetHeight(surface);
|
||||
+ if (getenv("DARLING_UI_GEOMETRY_TRACE")) {
|
||||
+ static __thread size_t previousWidth, previousHeight;
|
||||
+ if (width != previousWidth || height != previousHeight) {
|
||||
+ fprintf(stderr, "UI_GEOMETRY surface pid=%d pixels=%zux%zu route=%s\n",
|
||||
+ getpid(), width, height, readback ? "gpu-readback" : "software");
|
||||
+ previousWidth = width;
|
||||
+ previousHeight = height;
|
||||
+ }
|
||||
+ }
|
||||
+ size_t rowBytes = IOSurfaceGetBytesPerRow(surface);
|
||||
+ size_t dataSize = rowBytes * height;
|
||||
+ void *base = IOSurfaceGetBaseAddress(surface);
|
||||
@@ -6195,7 +6512,7 @@ index 5dcac115..7cc63b0b 100644
|
||||
|
||||
NSString *const kCAFilterLinear = @"linear";
|
||||
NSString *const kCAFilterNearest = @"nearest";
|
||||
@@ -61,13 +287,22 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
@@ -61,13 +296,22 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
}
|
||||
|
||||
- (void) setSublayers: (NSArray *) sublayers {
|
||||
@@ -6219,7 +6536,19 @@ index 5dcac115..7cc63b0b 100644
|
||||
}
|
||||
|
||||
- (id<CALayerDelegate>) delegate {
|
||||
@@ -171,14 +406,73 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
@@ -117,6 +361,11 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
[self addAnimation: action forKey: @"bounds"];
|
||||
}
|
||||
|
||||
+ if (!CGRectEqualToRect(_bounds, value) && getenv("DARLING_UI_GEOMETRY_TRACE") &&
|
||||
+ (value.size.width >= 256 || value.size.height >= 256))
|
||||
+ fprintf(stderr, "UI_GEOMETRY layer pid=%d class=%s bounds=%.0fx%.0f transform=%.3fx%.3f\n",
|
||||
+ getpid(), class_getName([self class]), value.size.width, value.size.height,
|
||||
+ _transform.m11, _transform.m22);
|
||||
_bounds = value;
|
||||
}
|
||||
|
||||
@@ -171,14 +420,73 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
_opaque = value;
|
||||
}
|
||||
|
||||
@@ -6293,7 +6622,19 @@ index 5dcac115..7cc63b0b 100644
|
||||
}
|
||||
|
||||
- (CATransform3D) transform {
|
||||
@@ -236,6 +530,10 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
@@ -186,6 +494,11 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
}
|
||||
|
||||
- (void) setTransform: (CATransform3D) value {
|
||||
+ if (getenv("DARLING_UI_GEOMETRY_TRACE") &&
|
||||
+ (_bounds.size.width >= 256 || _bounds.size.height >= 256))
|
||||
+ fprintf(stderr, "UI_GEOMETRY transform pid=%d class=%s bounds=%.0fx%.0f scale=%.3fx%.3f\n",
|
||||
+ getpid(), class_getName([self class]), _bounds.size.width, _bounds.size.height,
|
||||
+ value.m11, value.m22);
|
||||
_transform = value;
|
||||
}
|
||||
|
||||
@@ -236,6 +549,10 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
}
|
||||
|
||||
- (void) dealloc {
|
||||
@@ -6304,7 +6645,7 @@ index 5dcac115..7cc63b0b 100644
|
||||
[_sublayers release];
|
||||
[_animations release];
|
||||
[_minificationFilter release];
|
||||
@@ -258,6 +556,33 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
@@ -258,6 +575,33 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
[self setSublayers: [_sublayers arrayByAddingObject: layer]];
|
||||
}
|
||||
|
||||
@@ -6338,7 +6679,7 @@ index 5dcac115..7cc63b0b 100644
|
||||
- (void) replaceSublayer: (CALayer *) layer with: (CALayer *) other {
|
||||
NSMutableArray *layers = [_sublayers mutableCopy];
|
||||
NSUInteger index = [_sublayers indexOfObjectIdenticalTo: layer];
|
||||
@@ -298,9 +623,14 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
@@ -298,9 +642,14 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
}
|
||||
|
||||
- (void) removeFromSuperlayer {
|
||||
@@ -6354,7 +6695,7 @@ index 5dcac115..7cc63b0b 100644
|
||||
}
|
||||
|
||||
- (void) setNeedsDisplay {
|
||||
@@ -319,6 +649,19 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
@@ -319,6 +668,19 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
[_context startTimerIfNeeded];
|
||||
}
|
||||
|
||||
@@ -6374,7 +6715,7 @@ index 5dcac115..7cc63b0b 100644
|
||||
- (CAAnimation *) animationForKey: (NSString *) key {
|
||||
return [_animations objectForKey: key];
|
||||
}
|
||||
@@ -364,4 +707,119 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
@@ -364,4 +726,119 @@ NSString *const kCAContentsFormatGray8Uint = @"Gray8";
|
||||
_textureId = value;
|
||||
}
|
||||
|
||||
@@ -7881,3 +8222,34 @@ index ad5e4f9d..dbd997aa 100644
|
||||
-
|
||||
-@end
|
||||
\ No newline at end of file
|
||||
diff --git a/AppKit/NSGeometryTrace.h b/AppKit/NSGeometryTrace.h
|
||||
new file mode 100644
|
||||
index 00000000..a51a9241
|
||||
--- /dev/null
|
||||
+++ b/AppKit/NSGeometryTrace.h
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* Opt-in runtime geometry diagnostics; never log view text or client data. */
|
||||
+#ifndef DARLING_NS_GEOMETRY_TRACE_H
|
||||
+#define DARLING_NS_GEOMETRY_TRACE_H
|
||||
+#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+static inline void DarlingGeometryTrace(const char *format, ...) {
|
||||
+ if (!getenv("DARLING_UI_GEOMETRY_TRACE"))
|
||||
+ return;
|
||||
+ va_list args, copy;
|
||||
+ va_start(args, format);
|
||||
+ va_copy(copy, args);
|
||||
+ vfprintf(stderr, format, args);
|
||||
+ va_end(args);
|
||||
+ /* Clients may redirect stderr to a non-log descriptor. Keep a copy in
|
||||
+ * the guest's temporary directory so their resize events remain visible. */
|
||||
+ FILE *file = fopen("/tmp/darling-ui-geometry.log", "a");
|
||||
+ if (file) {
|
||||
+ vfprintf(file, format, copy);
|
||||
+ fclose(file);
|
||||
+ }
|
||||
+ va_end(copy);
|
||||
+}
|
||||
+#endif
|
||||
+822
-95
File diff suppressed because it is too large.
Load diff
+2
-162
@@ -3221,18 +3221,10 @@ index 0000000..479294a
|
||||
+ return -ENOSYS;
|
||||
+}
|
||||
diff --git a/darling/src/libsystem_kernel/emulation/src/xnu_syscall/bsd/impl/misc/proc_info.c b/darling/src/libsystem_kernel/emulation/src/xnu_syscall/bsd/impl/misc/proc_info.c
|
||||
index c2f70fb..73c2a5a 100644
|
||||
index c2f70fb..af904ed 100644
|
||||
--- a/darling/src/libsystem_kernel/emulation/src/xnu_syscall/bsd/impl/misc/proc_info.c
|
||||
+++ b/darling/src/libsystem_kernel/emulation/src/xnu_syscall/bsd/impl/misc/proc_info.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#define LINUX_PR_SET_NAME 15
|
||||
|
||||
static long _proc_pidinfo(int32_t pid, uint32_t flavor, uint64_t arg, void* buffer, int32_t bufsize);
|
||||
+static long _proc_listpids(uint32_t type, uint32_t typeinfo, void* buffer, int32_t bufsize);
|
||||
|
||||
extern __SIZE_TYPE__ strlen(const char *s);
|
||||
extern void *memset(void *s, int c, __SIZE_TYPE__ n);
|
||||
@@ -83,7 +84,42 @@ long sys_proc_info(uint32_t callnum, int32_t pid, uint32_t flavor,
|
||||
@@ -83,6 +83,38 @@ long sys_proc_info(uint32_t callnum, int32_t pid, uint32_t flavor,
|
||||
case 2: // proc_pidinfo
|
||||
return _proc_pidinfo(pid, flavor, arg, buffer, bufsize);
|
||||
case 3: // proc_pidfdinfo
|
||||
@@ -3269,160 +3261,8 @@ index c2f70fb..73c2a5a 100644
|
||||
+ return -ENOTSUP;
|
||||
+ }
|
||||
case 1: // proc_listpids
|
||||
+ // `pid` carries the process type and `flavor` carries the type
|
||||
+ // info (e.g. the pgid, ppid or uid to match).
|
||||
+ return _proc_listpids(pid, flavor, buffer, bufsize);
|
||||
default:
|
||||
__simple_printf("sys_proc_info(): Unsupported callnum: %d\n",
|
||||
callnum);
|
||||
@@ -827,3 +863,147 @@ bail:
|
||||
close_internal(fd);
|
||||
return count * sizeof(uint64_t);
|
||||
}
|
||||
+
|
||||
+// Returns whether `pid` should be included in a proc_listpids() query of the
|
||||
+// given `type`, matching the semantics of XNU's bsd/kern/proc_info.c.
|
||||
+static bool _proc_listpids_match(uint32_t type, uint32_t typeinfo, int32_t pid,
|
||||
+ int32_t uid)
|
||||
+{
|
||||
+ char path[64], stat[1024];
|
||||
+ char* statptr;
|
||||
+ const char* elem;
|
||||
+ int32_t ppid, pgrp, tty;
|
||||
+
|
||||
+ switch (type)
|
||||
+ {
|
||||
+ case PROC_ALL_PIDS:
|
||||
+ return true;
|
||||
+
|
||||
+ case PROC_UID_ONLY:
|
||||
+ case PROC_RUID_ONLY:
|
||||
+ // Darling's container runs every guest process as our own
|
||||
+ // user, which is also what _sysctl_proc() reports.
|
||||
+ return typeinfo == (uint32_t) uid;
|
||||
+
|
||||
+ case PROC_PGRP_ONLY:
|
||||
+ case PROC_PPID_ONLY:
|
||||
+ case PROC_TTY_ONLY:
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ // PROC_KDBG_ONLY and anything else: no process carries the
|
||||
+ // corresponding state under Darling.
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ __simple_sprintf(path, "/proc/%d/stat", pid);
|
||||
+ if (!read_string(path, stat, sizeof(stat)))
|
||||
+ return false;
|
||||
+
|
||||
+ statptr = stat;
|
||||
+ skip_stat_elems(&statptr, 1); // pid
|
||||
+
|
||||
+ if (!(elem = next_stat_elem(&statptr)))
|
||||
+ return false;
|
||||
+ // comm
|
||||
+
|
||||
+ if (!(elem = next_stat_elem(&statptr)))
|
||||
+ return false;
|
||||
+ // state
|
||||
+
|
||||
+ if (!(elem = next_stat_elem(&statptr)))
|
||||
+ return false;
|
||||
+ ppid = __simple_atoi(elem, NULL);
|
||||
+
|
||||
+ if (!(elem = next_stat_elem(&statptr)))
|
||||
+ return false;
|
||||
+ pgrp = __simple_atoi(elem, NULL);
|
||||
+
|
||||
+ if (type == PROC_PPID_ONLY)
|
||||
+ return ppid == (int32_t) typeinfo;
|
||||
+
|
||||
+ if (type == PROC_PGRP_ONLY)
|
||||
+ return pgrp == (int32_t) typeinfo;
|
||||
+
|
||||
+ // PROC_TTY_ONLY: the (Linux-encoded) controlling terminal device.
|
||||
+ if (!(elem = next_stat_elem(&statptr)))
|
||||
+ return false;
|
||||
+ // session
|
||||
+
|
||||
+ if (!(elem = next_stat_elem(&statptr)))
|
||||
+ return false;
|
||||
+ tty = __simple_atoi(elem, NULL);
|
||||
+
|
||||
+ return tty != 0 && (uint32_t) tty == typeinfo;
|
||||
+}
|
||||
+
|
||||
+// Emulates XNU's proc_listpids(), i.e. proc_info(PROC_INFO_CALL_LISTPIDS).
|
||||
+// Guest pids are Linux pids, so walking /proc gives the same set that the
|
||||
+// other proc_info flavors and sysctl(KERN_PROC_*) already operate on.
|
||||
+static long _proc_listpids(uint32_t type, uint32_t typeinfo, void* buffer, int32_t bufsize)
|
||||
+{
|
||||
+ char dents[256];
|
||||
+ long basep = 0;
|
||||
+ int fd, ret;
|
||||
+ int32_t maxpids, count = 0;
|
||||
+ static int uid = -1;
|
||||
+
|
||||
+ if (type != PROC_ALL_PIDS && type != PROC_PGRP_ONLY && type != PROC_TTY_ONLY &&
|
||||
+ type != PROC_UID_ONLY && type != PROC_RUID_ONLY &&
|
||||
+ type != PROC_PPID_ONLY && type != PROC_KDBG_ONLY)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (buffer && bufsize < (int32_t) sizeof(int))
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ // A null buffer asks for the size a caller should allocate.
|
||||
+ maxpids = buffer ? (bufsize / (int32_t) sizeof(int)) : 0;
|
||||
+
|
||||
+ if (uid == -1)
|
||||
+ uid = sys_getuid();
|
||||
+
|
||||
+ fd = sys_open_nocancel("/proc", BSD_O_RDONLY | BSD_O_DIRECTORY, 0);
|
||||
+ if (fd < 0)
|
||||
+ return fd;
|
||||
+
|
||||
+ while ((ret = sys_getdirentries(fd, (char*) dents, sizeof(dents), &basep)) > 0)
|
||||
+ {
|
||||
+ int pos = 0;
|
||||
+
|
||||
+ while (pos < ret)
|
||||
+ {
|
||||
+ struct bsd_dirent* dent = (struct bsd_dirent*) &dents[pos];
|
||||
+
|
||||
+ pos += dent->d_reclen;
|
||||
+
|
||||
+ if (dent->d_type != DT_DIR || !isdigit(dent->d_name[0]))
|
||||
+ continue;
|
||||
+
|
||||
+ int pid = __simple_atoi(dent->d_name, NULL);
|
||||
+
|
||||
+ if (!_proc_listpids_match(type, typeinfo, pid, uid))
|
||||
+ continue;
|
||||
+
|
||||
+ if (buffer)
|
||||
+ {
|
||||
+ // Truncate rather than overflow, like XNU does.
|
||||
+ if (count >= maxpids)
|
||||
+ goto bail;
|
||||
+
|
||||
+ ((int*) buffer)[count] = pid;
|
||||
+ }
|
||||
+
|
||||
+ ++count;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+bail:
|
||||
+ close_internal(fd);
|
||||
+
|
||||
+ // XNU reports a little extra headroom so that a size query followed by a
|
||||
+ // fill call cannot come up short when processes appear in between.
|
||||
+ if (!buffer)
|
||||
+ return (long)(count + 20) * sizeof(int);
|
||||
+
|
||||
+ return (long) count * sizeof(int);
|
||||
+}
|
||||
diff --git a/darling/src/libsystem_kernel/emulation/src/xnu_syscall/bsd/impl/misc/ptrace.c b/darling/src/libsystem_kernel/emulation/src/xnu_syscall/bsd/impl/misc/ptrace.c
|
||||
index 0a8f1e4..55aadbe 100644
|
||||
--- a/darling/src/libsystem_kernel/emulation/src/xnu_syscall/bsd/impl/misc/ptrace.c
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build only the changed GPU frame publisher and relink QuartzCore."""
|
||||
import shlex,subprocess
|
||||
"""Rebuild the patched QuartzCore compositor and Metal presentation objects."""
|
||||
import shlex
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
project=Path(__file__).resolve().parent.parent
|
||||
framework=project/'build/darling-src/build/src/external/cocotron/QuartzCore'
|
||||
flags={}
|
||||
for line in (framework/'CMakeFiles/QuartzCore.dir/flags.make').read_text().splitlines():
|
||||
if line.startswith('C_') and ' = ' in line:
|
||||
k,v=line.split(' = ',1);flags[k]=shlex.split(v)
|
||||
link=shlex.split((framework/'CMakeFiles/QuartzCore.dir/link.txt').read_text())
|
||||
for name in ('CALayer','CALayerContext','CATransaction'):
|
||||
obj=project/('build/m336-'+name+'.o')
|
||||
subprocess.run(['clang',*flags['C_DEFINES'],*flags['C_INCLUDES'],*flags['C_FLAGS'],'-O2','-Wno-macro-redefined','-c',str(project/('build/darling-src/src/external/cocotron/QuartzCore/'+name+'.m')),'-o',str(obj)],check=True)
|
||||
link[link.index('CMakeFiles/QuartzCore.dir/'+name+'.m.o')]=str(obj)
|
||||
link[link.index('-o')+1]=str(project/'build/m336-QuartzCore')
|
||||
subprocess.run(link,cwd=framework,check=True)
|
||||
print('Built isolated QuartzCore frame publisher')
|
||||
|
||||
project = Path(__file__).resolve().parent.parent
|
||||
framework = project / 'build/darling-src/build/src/external/cocotron/QuartzCore'
|
||||
flags = {}
|
||||
for line in (framework / 'CMakeFiles/QuartzCore.dir/flags.make').read_text().splitlines():
|
||||
if line.startswith(('C_', 'CXX_')) and ' = ' in line:
|
||||
key, value = line.split(' = ', 1)
|
||||
flags[key] = shlex.split(value)
|
||||
link = shlex.split((framework / 'CMakeFiles/QuartzCore.dir/link.txt').read_text())
|
||||
sources = ['CALayer.m', 'CALayerContext.m', 'CARenderer.m', 'CATransaction.m',
|
||||
'CATransactionGroup.m', 'CATransformLayer.m', 'CAMetalLayer.mm', 'CAMetalDrawable.mm']
|
||||
for source in sources:
|
||||
kind = 'CXX' if source.endswith('.mm') else 'C'
|
||||
obj = project / f'build/m336-{Path(source).stem}.o'
|
||||
subprocess.run(['clang++' if kind == 'CXX' else 'clang', *flags[kind + '_DEFINES'],
|
||||
*flags[kind + '_INCLUDES'], *flags[kind + '_FLAGS'], '-O2',
|
||||
'-Wno-macro-redefined', '-c',
|
||||
str(project / 'build/darling-src/src/external/cocotron/QuartzCore' / source),
|
||||
'-o', str(obj)], check=True)
|
||||
link[link.index(f'CMakeFiles/QuartzCore.dir/{source}.o')] = str(obj)
|
||||
link[link.index('-o') + 1] = str(project / 'build/m336-QuartzCore')
|
||||
subprocess.run(link, cwd=framework, check=True)
|
||||
print('Built isolated QuartzCore compositor and Metal presentation')
|
||||
@@ -21,7 +21,7 @@ for name in ['NSResponder', 'NSApplication', 'NSWindow', 'NSDisplay', 'NSView',
|
||||
link[link.index(f'CMakeFiles/AppKit.dir/{name}.m.o')] = str(obj)
|
||||
link[link.index('-o') + 1] = str(project / 'build/riot-AppKit')
|
||||
subprocess.run(link, cwd=framework, check=True)
|
||||
for name in ['riot-event-coalescing-check', 'riot-scroll-event-check', 'riot-appkit-pump-check', 'riot-window-layout-check', 'riot-game-input-check', 'riot-mouse-input-check']:
|
||||
for name in ['riot-event-coalescing-check', 'riot-scroll-event-check', 'riot-appkit-pump-check', 'riot-window-layout-check']:
|
||||
probe = project / f'build/{name}.o'
|
||||
subprocess.run(['clang', *flags['C_DEFINES'], *flags['C_INCLUDES'], *flags['C_FLAGS'],
|
||||
'-O2', '-fblocks', '-Wno-macro-redefined', '-c',
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Rebuild CarbonCore's legacy Gestalt version query and its standalone probe."""
|
||||
from pathlib import Path
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
root = Path(__file__).resolve().parent.parent
|
||||
folder = root / 'build/darling-src/build/src/frameworks/CoreServices/src/CarbonCore'
|
||||
flags = {}
|
||||
for line in (folder / 'CMakeFiles/CarbonCore.dir/flags.make').read_text().splitlines():
|
||||
if line.startswith(('C_', 'CXX_')) and ' = ' in line:
|
||||
key, value = line.split(' = ', 1)
|
||||
flags[key] = shlex.split(value)
|
||||
obj = root / 'build/riot-Gestalt.o'
|
||||
subprocess.run(['clang++', *flags['CXX_DEFINES'], *flags['CXX_INCLUDES'], *flags['CXX_FLAGS'],
|
||||
'-O2', '-Wno-macro-redefined', '-c',
|
||||
str(root / 'build/darling-src/src/frameworks/CoreServices/src/CarbonCore/Gestalt.cpp'),
|
||||
'-o', str(obj)], check=True)
|
||||
link = shlex.split((folder / 'CMakeFiles/CarbonCore.dir/link.txt').read_text())
|
||||
link[link.index('CMakeFiles/CarbonCore.dir/Gestalt.cpp.o')] = str(obj)
|
||||
link[link.index('-o') + 1] = str(root / 'build/riot-CarbonCore')
|
||||
subprocess.run(link, cwd=folder, check=True)
|
||||
probe = root / 'build/riot-gestalt-version-check.o'
|
||||
subprocess.run(['clang++', *flags['CXX_DEFINES'], *flags['CXX_INCLUDES'], *flags['CXX_FLAGS'],
|
||||
'-O2', '-Wno-macro-redefined', '-c', str(root / 'tools/riot-gestalt-version-check.cpp'),
|
||||
'-o', str(probe)], check=True)
|
||||
subprocess.run(['clang++', '-target', 'x86_64-apple-macosx11.0', '-fuse-ld=lld', '-nostdlib',
|
||||
'-isysroot', '@DARLING_SDK@', str(probe), str(root / 'build/riot-CarbonCore'),
|
||||
'-lSystem', '-lc++', '-o', str(root / 'build/riot-gestalt-version-check')], check=True)
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build an owned X11/IOSurface window that verifies pixels after resizing."""
|
||||
from pathlib import Path
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
root = Path(__file__).resolve().parent.parent
|
||||
folder = root / 'build/darling-src/build/src/external/cocotron/AppKit'
|
||||
flags = {}
|
||||
for line in (folder / 'CMakeFiles/X11_backend.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-client-resize-check.o'
|
||||
subprocess.run(['clang', *flags['C_DEFINES'], *flags['C_INCLUDES'], *flags['C_FLAGS'],
|
||||
'-O2', '-Wno-macro-redefined', '-c', str(root / 'tools/riot-client-resize-check.m'),
|
||||
'-o', str(obj)], check=True)
|
||||
subprocess.run(['clang', '-target', 'x86_64-apple-macosx11.0', '-fuse-ld=lld', '-nostdlib',
|
||||
'-isysroot', '@DARLING_SDK@', str(obj), '-lSystem', '-lobjc',
|
||||
'-framework', 'AppKit', '-framework', 'QuartzCore', '-framework', 'OpenGL',
|
||||
'-framework', 'IOSurface', '-framework', 'CoreFoundation', '-framework', 'Foundation',
|
||||
str(root / 'build/darling-src/build/src/native/libX11.dylib'),
|
||||
'-o', str(root / 'build/riot-client-resize-check')], check=True)
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build CoreText's font-list compatibility override and standalone regression."""
|
||||
from pathlib import Path
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
root = Path(__file__).resolve().parent.parent
|
||||
folder = root / 'build/darling-src/build/src/external/cocotron/CoreText'
|
||||
flags = {}
|
||||
for line in (folder / 'CMakeFiles/CoreText.dir/flags.make').read_text().splitlines():
|
||||
if line.startswith('C_') and ' = ' in line:
|
||||
key, value = line.split(' = ', 1)
|
||||
flags[key] = shlex.split(value)
|
||||
link = shlex.split((folder / 'CMakeFiles/CoreText.dir/link.txt').read_text())
|
||||
for name in ['CTFontDescriptor', 'CTFontManager']:
|
||||
obj = root / f'build/riot-{name}.o'
|
||||
subprocess.run(['clang', *flags['C_DEFINES'], *flags['C_INCLUDES'], *flags['C_FLAGS'],
|
||||
'-O2', '-Wno-macro-redefined', '-c',
|
||||
str(root / f'build/darling-src/src/external/cocotron/CoreText/{name}.m'),
|
||||
'-o', str(obj)], check=True)
|
||||
link[link.index(f'CMakeFiles/CoreText.dir/{name}.m.o')] = str(obj)
|
||||
link[link.index('-o') + 1] = str(root / 'build/riot-CoreText')
|
||||
fontconfig = str(root / 'build/darling-src/build/src/native/libfontconfig.dylib')
|
||||
if not any(value.endswith('/libfontconfig.dylib') and not value.startswith('-') for value in link):
|
||||
link.append(fontconfig)
|
||||
subprocess.run(link, cwd=folder, check=True)
|
||||
obj = root / 'build/riot-coretext-font-list-check.o'
|
||||
subprocess.run(['clang', *flags['C_DEFINES'], *flags['C_INCLUDES'], *flags['C_FLAGS'],
|
||||
'-O2', '-Wno-macro-redefined', '-c', str(root / 'tools/riot-coretext-font-list-check.m'),
|
||||
'-o', str(obj)], check=True)
|
||||
subprocess.run(['clang', '-target', 'x86_64-apple-macosx11.0', '-fuse-ld=lld', '-nostdlib',
|
||||
'-isysroot', '@DARLING_SDK@', str(obj), str(root / 'build/riot-CoreText'),
|
||||
'-lSystem', '-lobjc', '-framework', 'Foundation', '-framework', 'CoreFoundation',
|
||||
'-o', str(root / 'build/riot-coretext-font-list-check')], check=True)
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/bin/sh
|
||||
# Install the rebuilt AppKit overlay and its paired X11 backend.
|
||||
# Manually exit the game and both clients, then shut down Darling before use.
|
||||
set -eu
|
||||
project_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
guest_home=${RIOT_GUEST_HOME:-$HOME/.darling@GUEST_HOME@}
|
||||
framework="$guest_home/RuntimeFrameworks/AppKit.framework/Versions/C"
|
||||
backup_dir=${RIOT_APPKIT_BACKUP_DIR:-$project_dir/build/appkit-runtime-backups}
|
||||
# Preflight both artifacts and destinations before replacing either binary.
|
||||
for name in AppKit X11; do
|
||||
case "$name" in
|
||||
AppKit) artifact=${RIOT_APPKIT_ARTIFACT:-$project_dir/build/riot-AppKit}; binary="$framework/AppKit";;
|
||||
X11) artifact=${RIOT_X11_ARTIFACT:-$project_dir/build/riot-X11}; binary="$framework/Resources/Backends/X11.backend/Contents/MacOS/X11";;
|
||||
esac
|
||||
[ -f "$artifact" ] || { echo "Build $name first: $artifact" >&2; exit 1; }
|
||||
[ -f "$binary" ] && [ ! -L "$binary" ] || {
|
||||
echo "Expected an existing $name overlay: $binary" >&2; exit 1;
|
||||
}
|
||||
done
|
||||
mkdir -p "$backup_dir"
|
||||
for name in AppKit X11; do
|
||||
case "$name" in
|
||||
AppKit) artifact=${RIOT_APPKIT_ARTIFACT:-$project_dir/build/riot-AppKit}; binary="$framework/AppKit";;
|
||||
X11) artifact=${RIOT_X11_ARTIFACT:-$project_dir/build/riot-X11}; binary="$framework/Resources/Backends/X11.backend/Contents/MacOS/X11";;
|
||||
esac
|
||||
if cmp -s "$artifact" "$binary"; then
|
||||
echo "$name is already current."
|
||||
continue
|
||||
fi
|
||||
old_hash=$(sha256sum "$binary" | cut -d ' ' -f 1)
|
||||
backup="$backup_dir/$name-$old_hash"
|
||||
if [ -e "$backup" ]; then
|
||||
cmp -s "$binary" "$backup" || { echo "Backup verification failed: $backup" >&2; exit 1; }
|
||||
else
|
||||
cp -p "$binary" "$backup"
|
||||
fi
|
||||
staged=$(mktemp "$binary.staged.XXXXXX")
|
||||
trap 'rm -f "$staged"' EXIT HUP INT TERM
|
||||
install -m755 "$artifact" "$staged"
|
||||
cmp -s "$artifact" "$staged" || { echo "Staged $name verification failed" >&2; exit 1; }
|
||||
mv -f "$staged" "$binary"
|
||||
echo "$name installed. Backup: $backup"
|
||||
done
|
||||
echo "Launch scripts/run.sh to use the new runtime."
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
# Install the corrected legacy system-version API into the stopped guest prefix.
|
||||
# Exit the game and both clients, then run darling shutdown before this script.
|
||||
set -eu
|
||||
project_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
prefix_dir=${DPREFIX:-@DPREFIX@}
|
||||
guest_home=${RIOT_GUEST_HOME:-$prefix_dir@GUEST_HOME@}
|
||||
artifact=${RIOT_CARBONCORE_ARTIFACT:-$project_dir/build/riot-CarbonCore}
|
||||
backup_dir=${RIOT_CARBONCORE_BACKUP_DIR:-$project_dir/build/carboncore-runtime-backups}
|
||||
sdk_framework="@DARLING_SDK@/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework"
|
||||
framework="$guest_home/RuntimeFrameworks/CarbonCore.framework"
|
||||
prefix_binary="$prefix_dir/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore"
|
||||
[ -f "$artifact" ] || { echo "Build CarbonCore first: $artifact" >&2; exit 1; }
|
||||
[ -f "$sdk_framework/Versions/A/CarbonCore" ] || { echo "Missing SDK CarbonCore framework" >&2; exit 1; }
|
||||
mkdir -p "$guest_home/RuntimeFrameworks" "$backup_dir"
|
||||
if [ ! -d "$framework" ]; then
|
||||
cp -a "$sdk_framework" "$framework"
|
||||
fi
|
||||
for binary in "$framework/Versions/A/CarbonCore" "$prefix_binary"; do
|
||||
if [ -L "$binary" ]; then echo "Expected a regular binary: $binary" >&2; exit 1; fi
|
||||
if [ -f "$binary" ] && cmp -s "$artifact" "$binary"; then continue; fi
|
||||
previous="$binary"
|
||||
if [ ! -f "$previous" ]; then previous="$sdk_framework/Versions/A/CarbonCore"; fi
|
||||
old_hash=$(sha256sum "$previous" | cut -d ' ' -f 1)
|
||||
backup="$backup_dir/CarbonCore-$old_hash"
|
||||
if [ -e "$backup" ]; then
|
||||
cmp -s "$previous" "$backup" || { echo "Backup verification failed: $backup" >&2; exit 1; }
|
||||
else
|
||||
cp -p "$previous" "$backup"
|
||||
fi
|
||||
mkdir -p "$(dirname -- "$binary")"
|
||||
staged=$(mktemp "$binary.staged.XXXXXX")
|
||||
trap 'rm -f "$staged"' EXIT HUP INT TERM
|
||||
install -m755 "$artifact" "$staged"
|
||||
cmp -s "$artifact" "$staged" || { echo "Staged CarbonCore verification failed" >&2; exit 1; }
|
||||
mv -f "$staged" "$binary"
|
||||
done
|
||||
echo "CarbonCore installed; backups: $backup_dir"
|
||||
echo "Launch scripts/run.sh to activate it."
|
||||
@@ -14,6 +14,8 @@ python3 tools/build-m58f341-corevideo.py
|
||||
python3 tools/build-riot-x11-runtime.py
|
||||
python3 tools/build-riot-appkit-runtime.py
|
||||
python3 tools/build-riot-coregraphics-runtime.py
|
||||
python3 tools/build-riot-coretext-runtime.py
|
||||
python3 tools/build-riot-carboncore-runtime.py
|
||||
python3 tools/build-riot-corefoundation-runtime.py
|
||||
python3 tools/build-riot-kqueue-runtime.py
|
||||
python3 tools/build-riot-malloc-runtime.py
|
||||
@@ -31,7 +33,7 @@ python3 tools/stop-darling-runtime.py
|
||||
sudo make -C "$project_dir/build/darling-src/build/src/external/darlingserver" install -j12
|
||||
# Electron's window-visibility correction lives in the AppKit overlay
|
||||
# (NSWindow -occlusionState, cocotron.patch); no Riot binary is modified here.
|
||||
for name in IOSurface OpenGL QuartzCore CoreVideo CoreAudio AudioToolbox CoreGraphics CoreFoundation Metal; do
|
||||
for name in IOSurface OpenGL QuartzCore CoreVideo CoreAudio AudioToolbox CoreGraphics CoreText CoreFoundation Metal; do
|
||||
framework="$guest_home/RuntimeFrameworks/$name.framework"
|
||||
if [ ! -d "$framework" ]; then cp -a "@DARLING_SDK@/System/Library/Frameworks/$name.framework" "$framework"; fi
|
||||
binary="$framework/Versions/A/$name"
|
||||
@@ -39,13 +41,13 @@ for name in IOSurface OpenGL QuartzCore CoreVideo CoreAudio AudioToolbox CoreGra
|
||||
case "$name" in
|
||||
IOSurface) source=build/m333-IOSurface;;
|
||||
OpenGL) source=build/m327-OpenGL;;
|
||||
QuartzCore)
|
||||
if [ -f build/riot-QuartzCore ]; then source=build/riot-QuartzCore;
|
||||
else source=build/m336-QuartzCore; fi;;
|
||||
# Use the artifact rebuilt by this invocation, not an older optional probe build.
|
||||
QuartzCore) source=build/m336-QuartzCore;;
|
||||
CoreVideo) source=build/m341-CoreVideo;;
|
||||
CoreAudio) source=build/riot-CoreAudio;;
|
||||
AudioToolbox) source=build/riot-AudioToolbox;;
|
||||
CoreGraphics) source=build/riot-CoreGraphics;;
|
||||
CoreText) source=build/riot-CoreText;;
|
||||
CoreFoundation) source=build/riot-CoreFoundation;;
|
||||
Metal) source=build/riot-Metal;;
|
||||
esac
|
||||
@@ -54,6 +56,8 @@ for name in IOSurface OpenGL QuartzCore CoreVideo CoreAudio AudioToolbox CoreGra
|
||||
# Dyld resolves Versions/A. Preserve the standard outer symlink as well.
|
||||
if [ ! -L "$framework/$name" ]; then rm -f "$framework/$name"; ln -s "Versions/Current/$name" "$framework/$name"; fi
|
||||
done
|
||||
# Legacy version queries must also reach the corrected absolute subframework.
|
||||
sh tools/install-riot-carboncore-runtime.sh
|
||||
# Re-exported GL symbols use the native library's absolute install name.
|
||||
# DYLD_LIBRARY_PATH must see this rebuilt wrapper as well as the framework copy.
|
||||
mkdir -p "$guest_home/RuntimeLibraries"
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <QuartzCore/CALayer.h>
|
||||
#import <QuartzCore/CATransaction.h>
|
||||
#import <IOSurface/IOSurface.h>
|
||||
#import <X11/Xlib.h>
|
||||
#import <X11/Xutil.h>
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#import <OpenGL/gl.h>
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@interface NSObject (NativeWindowID)
|
||||
- (unsigned long)windowHandle;
|
||||
@end
|
||||
static void pump(double seconds) {
|
||||
NSDate *end=[NSDate dateWithTimeIntervalSinceNow:seconds];
|
||||
while([end timeIntervalSinceNow]>0) {
|
||||
NSEvent *e=[NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
|
||||
if(e)[NSApp sendEvent:e];
|
||||
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.005]];
|
||||
}
|
||||
}
|
||||
static IOSurfaceRef surface(int width,int height,int generation) {
|
||||
int dims[]={width,height,4,width*4,0x42475241};
|
||||
const void *keys[]={kIOSurfaceWidth,kIOSurfaceHeight,kIOSurfaceBytesPerElement,kIOSurfaceBytesPerRow,kIOSurfacePixelFormat},*values[5];
|
||||
for(int i=0;i<5;i++)values[i]=CFNumberCreate(NULL,kCFNumberIntType,&dims[i]);
|
||||
CFDictionaryRef options=CFDictionaryCreate(NULL,keys,values,5,&kCFTypeDictionaryKeyCallBacks,&kCFTypeDictionaryValueCallBacks);
|
||||
IOSurfaceRef s=IOSurfaceCreate(options);CFRelease(options);for(int i=0;i<5;i++)CFRelease(values[i]);
|
||||
if(!s)return NULL;
|
||||
unsigned char *pixels=IOSurfaceGetBaseAddress(s);size_t stride=IOSurfaceGetBytesPerRow(s);
|
||||
for(int y=0;y<height;y++)for(int x=0;x<width;x++){unsigned char *p=pixels+y*stride+x*4;p[0]=x<width/2?0:255;p[1]=y<height/2?255:0;p[2]=40+generation*40;p[3]=255;}
|
||||
return s;
|
||||
}
|
||||
/* Exercise the transport protocol with two owned fixture publishers. The
|
||||
* software owner changes to a popup while readback supplies the resized main
|
||||
* window, as happens when a browser GPU process serves multiple windows. */
|
||||
typedef struct {
|
||||
uint32_t magic, sequence, width, height, stride, format;
|
||||
uint64_t size;
|
||||
} FixtureFrame;
|
||||
static BOOL writeFixture(const char *path,int width,int height,int generation,BOOL software) {
|
||||
IOSurfaceRef s=surface(width,height,generation);if(!s)return NO;
|
||||
size_t stride=IOSurfaceGetBytesPerRow(s),bytes=stride*height;
|
||||
int fd=open(path,O_CREAT|O_RDWR,0600);
|
||||
BOOL ok=fd>=0 && ftruncate(fd,32+64u*1024u*1024u)==0;
|
||||
static uint32_t sequence=0;sequence+=2;
|
||||
FixtureFrame head={0x43414652u,sequence|1,width,height,(uint32_t)stride,
|
||||
0x42475241u|(software?0x80000000u:0),bytes};
|
||||
if(ok)ok=pwrite(fd,&head,sizeof(head),0)==sizeof(head) &&
|
||||
pwrite(fd,IOSurfaceGetBaseAddress(s),bytes,sizeof(head))==(ssize_t)bytes;
|
||||
head.sequence=sequence;
|
||||
if(ok)ok=pwrite(fd,&head,sizeof(head),0)==sizeof(head);
|
||||
if(fd>=0)close(fd);CFRelease(s);return ok;
|
||||
}
|
||||
static int checkPublisherHandoff(void) {
|
||||
char owner[128],readback[128];
|
||||
snprintf(owner,sizeof(owner),"/dev/shm/darling-ca-frame-%u-%d",getuid(),getpid());
|
||||
snprintf(readback,sizeof(readback),"/dev/shm/darling-ca-frame-%u-%d",getuid(),getpid()+100000000);
|
||||
NSWindow *w=[[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,1280,720)
|
||||
styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
|
||||
[w setTitle:@"Darling standalone publisher handoff"];
|
||||
[w makeKeyAndOrderFront:nil];
|
||||
Display *d=XOpenDisplay(NULL);Window xid=[(id)[w platformWindow] windowHandle];
|
||||
BOOL pass=d!=NULL;
|
||||
int sizes[][2]={{1280,720},{1600,900},{1024,576},{1280,720}};
|
||||
for(int n=0;pass && n<4;n++) {
|
||||
int width=sizes[n][0],height=sizes[n][1];
|
||||
[w setContentSize:NSMakeSize(width,height)];
|
||||
if(n==0)pass=writeFixture(owner,width,height,n,YES);
|
||||
else pass=writeFixture(owner,262,131,0,YES) &&
|
||||
writeFixture(readback,width,height,n,NO);
|
||||
BOOL ok=NO;unsigned long pixel=0;
|
||||
NSDate *deadline=[NSDate dateWithTimeIntervalSinceNow:3.0];
|
||||
while(pass && !ok && [deadline timeIntervalSinceNow]>0) {
|
||||
pump(.05);XSync(d,False);
|
||||
XImage *im=XGetImage(d,xid,0,0,width,height,AllPlanes,ZPixmap);
|
||||
if(im){pixel=XGetPixel(im,width-8,height-8)&0xffffff;
|
||||
ok=pixel==(((unsigned long)(40+n*40)<<16)|0xff);XDestroyImage(im);}
|
||||
}
|
||||
printf("PUBLISHER_HANDOFF size=%dx%d bottom_right=%06lx pass=%d\n",width,height,pixel,ok);
|
||||
pass &=ok;
|
||||
}
|
||||
[w orderOut:nil];[w release];if(d)XCloseDisplay(d);
|
||||
unlink(owner);unlink(readback);return pass?0:1;
|
||||
}
|
||||
int main(int argc, const char **argv) {
|
||||
@autoreleasepool {
|
||||
[NSApplication sharedApplication];
|
||||
if(argc>1 && strcmp(argv[1],"--handoff")==0)return checkPublisherHandoff();
|
||||
NSWindow *w=[[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,1280,720) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
|
||||
[w setTitle:@"Darling standalone resize pixels"];
|
||||
NSView *view=[w contentView];[view setWantsLayer:YES];
|
||||
[w makeKeyAndOrderFront:nil];pump(.15);
|
||||
Display *d=XOpenDisplay(NULL);Window xid=[(id)[w platformWindow] windowHandle];
|
||||
void (*publish)(IOSurfaceRef)=dlsym(RTLD_DEFAULT,"DarlingCAPublishIOSurfacePixels");
|
||||
if(!d||!publish)return 2;
|
||||
BOOL useGPU = argc > 1 && strcmp(argv[1], "--gpu") == 0;
|
||||
IOSurfaceRef bootstrap=surface(1280,720,0);
|
||||
[view.layer setContents:(id)bootstrap];publish(bootstrap);pump(.5);CFRelease(bootstrap);
|
||||
CGLPixelFormatAttribute attrs[]={0};CGLPixelFormatObj format;GLint screens;CGLContextObj gpu;
|
||||
GLuint texture=0;
|
||||
if(useGPU) {
|
||||
if(CGLChoosePixelFormat(attrs,&format,&screens)||CGLCreateContext(format,NULL,&gpu))return 4;
|
||||
CGLSetCurrentContext(gpu);glGenTextures(1,&texture);
|
||||
}
|
||||
BOOL pass=YES;
|
||||
int sizes[][2]={{1280,720},{1600,900},{1024,576},{1280,720}};
|
||||
for(int n=0;n<4;n++) {
|
||||
int width=sizes[n][0],height=sizes[n][1];
|
||||
[w setContentSize:NSMakeSize(width,height)];
|
||||
IOSurfaceRef s=surface(width,height,n);if(!s)return 3;
|
||||
if(useGPU) {
|
||||
CGLSetCurrentContext(gpu);glBindTexture(GL_TEXTURE_RECTANGLE,texture);
|
||||
if(CGLTexImageIOSurface2D(gpu,GL_TEXTURE_RECTANGLE,GL_RGBA8,width,height,GL_BGRA,GL_UNSIGNED_INT_8_8_8_8_REV,s,0))return 5;
|
||||
}
|
||||
for(int f=0;f<8;f++) {
|
||||
if(useGPU)CGLSetCurrentContext(gpu);
|
||||
[view.layer setContents:(id)s];
|
||||
if(!useGPU)publish(s);
|
||||
[CATransaction flush];pump(.1);
|
||||
}
|
||||
BOOL ok=NO;
|
||||
unsigned long pixel=0;
|
||||
NSDate *deadline=[NSDate dateWithTimeIntervalSinceNow:2.5];
|
||||
do {
|
||||
XSync(d,False);
|
||||
XImage *im=XGetImage(d,xid,0,0,width,height,AllPlanes,ZPixmap);
|
||||
if(im) {
|
||||
pixel=XGetPixel(im,width-8,height-8)&0xffffff;
|
||||
ok=pixel==(((unsigned long)(40+n*40)<<16)|0xff);
|
||||
XDestroyImage(im);
|
||||
}
|
||||
if(!ok)pump(.05);
|
||||
} while(!ok && [deadline timeIntervalSinceNow]>0);
|
||||
printf("RESIZE_PIXEL mode=%s size=%dx%d view=%.0fx%.0f bottom_right=%06lx pass=%d\n",
|
||||
useGPU?"gpu":"software",width,height,view.frame.size.width,view.frame.size.height,pixel,ok);
|
||||
pass &=ok;CFRelease(s);
|
||||
}
|
||||
if(useGPU){CGLSetCurrentContext(gpu);glDeleteTextures(1,&texture);CGLSetCurrentContext(NULL);CGLReleaseContext(gpu);CGLReleasePixelFormat(format);}
|
||||
[w orderOut:nil];[w release];XCloseDisplay(d);
|
||||
return pass?0:1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreText/CTFontDescriptor.h>
|
||||
#import <CoreText/CTFontManager.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void verifyFontList(BOOL pass, const char *message) {
|
||||
if (!pass) { fprintf(stderr, "CORETEXT_FONT_LIST FAIL: %s\n", message); exit(1); }
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
@autoreleasepool {
|
||||
CFArrayRef families = CTFontManagerCopyAvailableFontFamilyNames();
|
||||
verifyFontList(families && CFArrayGetCount(families) > 0, "installed font families");
|
||||
const void *key = kCTFontFamilyNameAttribute;
|
||||
CFSetRef mandatory = CFSetCreate(NULL, &key, 1, &kCFTypeSetCallBacks);
|
||||
unsigned faces = 0;
|
||||
for (NSString *family in (NSArray *)families) {
|
||||
NSDictionary *attributes = [NSDictionary dictionaryWithObject:family forKey:(id)key];
|
||||
CTFontDescriptorRef query = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)attributes);
|
||||
CFArrayRef matches = CTFontDescriptorCreateMatchingFontDescriptors(query, mandatory);
|
||||
verifyFontList(matches && CFArrayGetCount(matches) > 0, "family resolves to installed faces");
|
||||
for (CFIndex i = 0; i < CFArrayGetCount(matches); ++i) {
|
||||
CTFontDescriptorRef match = (CTFontDescriptorRef)CFArrayGetValueAtIndex(matches, i);
|
||||
CFStringRef name = CTFontDescriptorCopyAttribute(match, kCTFontFamilyNameAttribute);
|
||||
verifyFontList(name && CFEqual(name, (CFStringRef)family), "mandatory family matches exactly");
|
||||
CFStringRef localized = CTFontDescriptorCopyLocalizedAttribute(match, kCTFontFamilyNameAttribute, NULL);
|
||||
verifyFontList(localized && CFGetTypeID(localized) == CFStringGetTypeID(), "localized lookup with null output");
|
||||
CFRelease(localized); CFRelease(name); ++faces;
|
||||
}
|
||||
CTFontDescriptorRef first = CTFontDescriptorCreateMatchingFontDescriptor(query, mandatory);
|
||||
verifyFontList(first != NULL, "single matching descriptor");
|
||||
CFRelease(query); CFRelease(matches);
|
||||
/* The single-match result must outlive its temporary array. */
|
||||
CFTypeRef name = CTFontDescriptorCopyAttribute(first, kCTFontNameAttribute);
|
||||
verifyFontList(name != NULL, "retained single descriptor and normalized PostScript name");
|
||||
CFRelease(name); CFRelease(first);
|
||||
}
|
||||
NSDictionary *missing = [NSDictionary dictionaryWithObject:@"DarlingMissingFont-7259AEB1" forKey:(id)key];
|
||||
CTFontDescriptorRef query = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)missing);
|
||||
CFArrayRef matches = CTFontDescriptorCreateMatchingFontDescriptors(query, mandatory);
|
||||
verifyFontList(!matches || !CFArrayGetCount(matches), "missing mandatory family has no substitutes");
|
||||
verifyFontList(!CTFontDescriptorCreateMatchingFontDescriptor(query, mandatory), "no single match for missing font");
|
||||
CFStringRef language = CFSTR("sentinel");
|
||||
verifyFontList(!CTFontDescriptorCopyLocalizedAttribute(query, kCTFontStyleNameAttribute, &language) && !language,
|
||||
"missing attribute initializes language output");
|
||||
if (matches) CFRelease(matches);
|
||||
CFRelease(query); CFRelease(mandatory);
|
||||
printf("CORETEXT_FONT_LIST pass=1 families=%ld faces=%u\n", CFArrayGetCount(families), faces);
|
||||
CFRelease(families);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <CarbonCore/MacErrors.h>
|
||||
#include <CarbonCore/Gestalt.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
char product[64] = {};
|
||||
size_t size = sizeof(product);
|
||||
int expectedMajor = 0, expectedMinor = 0, expectedPatch = 0;
|
||||
if (sysctlbyname("kern.osproductversion", product, &size, nullptr, 0) ||
|
||||
sscanf(product, "%d.%d.%d", &expectedMajor, &expectedMinor, &expectedPatch) < 1)
|
||||
return 2;
|
||||
int major = -1, minor = -1, patch = -1, packed = -1, architecture = -1;
|
||||
bool pass = !Gestalt(gestaltSystemVersionMajor, &major) && major == expectedMajor &&
|
||||
!Gestalt(gestaltSystemVersionMinor, &minor) && minor == expectedMinor &&
|
||||
!Gestalt(gestaltSystemVersionPatch, &patch) && patch == expectedPatch;
|
||||
int expectedPacked = ((((expectedMajor / 10) << 4) | (expectedMajor % 10)) << 8) |
|
||||
((expectedMinor > 9 ? 9 : expectedMinor) << 4) | (expectedPatch > 9 ? 9 : expectedPatch);
|
||||
pass &= !Gestalt(gestaltSystemVersion, &packed) && packed == expectedPacked;
|
||||
pass &= !Gestalt(gestaltSysArchitecture, &architecture) && architecture == gestaltIntel;
|
||||
pass &= Gestalt(gestaltSystemVersionMajor, nullptr) == paramErr;
|
||||
int unknown = 123;
|
||||
pass &= Gestalt(0, &unknown) == unimpErr && unknown == 0;
|
||||
printf("GESTALT_VERSION product=%s version=%d.%d.%d packed=0x%x architecture=%d pass=%d\n",
|
||||
product, major, minor, patch, packed, architecture, pass);
|
||||
return pass ? 0 : 1;
|
||||
}
|
||||
@@ -1,6 +1,36 @@
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <QuartzCore/CALayer.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@interface ResizeOrderView : NSView {
|
||||
@public
|
||||
NSSize nativeSizeDuringResize;
|
||||
}
|
||||
@end
|
||||
@implementation ResizeOrderView
|
||||
- (void)setFrame:(NSRect)frame {
|
||||
if ([self window])
|
||||
nativeSizeDuringResize = [(id)[[self window] platformWindow] frame].size;
|
||||
[super setFrame:frame];
|
||||
}
|
||||
@end
|
||||
|
||||
/* Browser compositors publish their new viewport from setFrameSize:, even
|
||||
* when AppKit or their parent sets a complete frame rectangle. */
|
||||
@interface FrameSizeHookView : NSView {
|
||||
@public
|
||||
NSUInteger sizeCallbacks;
|
||||
NSSize publishedSize;
|
||||
}
|
||||
@end
|
||||
@implementation FrameSizeHookView
|
||||
- (void)setFrameSize:(NSSize)size {
|
||||
[super setFrameSize:size];
|
||||
sizeCallbacks++;
|
||||
publishedSize = [self frame].size;
|
||||
}
|
||||
@end
|
||||
|
||||
int main(void) {
|
||||
@autoreleasepool {
|
||||
[NSApplication sharedApplication];
|
||||
@@ -21,6 +51,69 @@ int main(void) {
|
||||
pass &= NSEqualSizes(changed, [ordinary frame].size);
|
||||
[full setFrame:NSMakeRect(20, 20, 900, 500) display:NO];
|
||||
pass &= NSEqualSizes([[full contentView] frame].size, NSMakeSize(900, 500));
|
||||
/* Layer geometry must be current before any coordinate conversion or
|
||||
* input event. Chromium submits compositor surfaces during resize. */
|
||||
NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 1280, 720)];
|
||||
[view setWantsLayer:YES];
|
||||
[view setFrameSize:NSMakeSize(1600, 900)];
|
||||
NSSize layerSize = [[view layer] bounds].size;
|
||||
BOOL layers = NSEqualSizes(layerSize, NSMakeSize(1600, 900));
|
||||
[view setBounds:NSMakeRect(10, 20, 800, 450)];
|
||||
layers &= NSEqualRects([[view layer] bounds], NSMakeRect(10, 20, 800, 450));
|
||||
[view setFrameSize:NSMakeSize(1280, 720)];
|
||||
layers &= NSEqualSizes([[view layer] bounds].size, NSMakeSize(640, 360));
|
||||
NSView *child = [[NSView alloc] initWithFrame:NSMakeRect(5, 6, 20, 30)];
|
||||
[view addSubview:child];
|
||||
[child setFrame:NSMakeRect(12, 18, 40, 50)];
|
||||
layers &= NSEqualRects([[child layer] frame], NSMakeRect(12, 18, 40, 50));
|
||||
printf("VIEW_LAYER_RESIZE initial=%.0fx%.0f pass=%d\n", layerSize.width, layerSize.height, layers);
|
||||
pass &= layers;
|
||||
NSWindow *native = [[NSWindow alloc] initWithContentRect:rect styleMask:NSBorderlessWindowMask
|
||||
backing:NSBackingStoreBuffered defer:NO];
|
||||
ResizeOrderView *content = [[ResizeOrderView alloc] initWithFrame:rect];
|
||||
[native setContentView:content];
|
||||
[native platformWindow];
|
||||
[native setFrame:NSMakeRect(20, 20, 1600, 900) display:NO];
|
||||
BOOL nativeOrder = NSEqualSizes(content->nativeSizeDuringResize, NSMakeSize(1600, 900));
|
||||
printf("NATIVE_RESIZE_ORDER size=%.0fx%.0f pass=%d\n", content->nativeSizeDuringResize.width,
|
||||
content->nativeSizeDuringResize.height, nativeOrder);
|
||||
pass &= nativeOrder;
|
||||
/* Chromium adds titlebar/overlay siblings after the actual content.
|
||||
* Frame layout must not mistake the last sibling for the content. */
|
||||
NSView *overlay = [[NSView alloc] initWithFrame:NSMakeRect(4, 5, 30, 20)];
|
||||
[[[native contentView] superview] addSubview:overlay];
|
||||
[native setContentSize:NSMakeSize(1280, 720)];
|
||||
BOOL siblings = NSEqualSizes([[native contentView] frame].size, NSMakeSize(1280, 720)) &&
|
||||
NSEqualSizes([overlay frame].size, NSMakeSize(30, 20));
|
||||
printf("CONTENT_SIBLING_RESIZE content=%.0fx%.0f overlay=%.0fx%.0f pass=%d\n",
|
||||
[[native contentView] frame].size.width, [[native contentView] frame].size.height,
|
||||
[overlay frame].size.width, [overlay frame].size.height, siblings);
|
||||
pass &= siblings;
|
||||
NSView *host = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 1280, 720)];
|
||||
FrameSizeHookView *viewport = [[FrameSizeHookView alloc]
|
||||
initWithFrame:NSMakeRect(0, 0, 1280, 720)];
|
||||
[viewport setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[host addSubview:viewport];
|
||||
[host setFrame:NSMakeRect(0, 0, 1600, 900)];
|
||||
BOOL hooks = viewport->sizeCallbacks == 1 &&
|
||||
NSEqualSizes(viewport->publishedSize, NSMakeSize(1600, 900));
|
||||
[host setFrame:NSMakeRect(0, 0, 1024, 576)];
|
||||
hooks &= viewport->sizeCallbacks == 2 &&
|
||||
NSEqualSizes(viewport->publishedSize, NSMakeSize(1024, 576));
|
||||
[viewport setFrame:NSMakeRect(3, 4, 800, 450)];
|
||||
hooks &= viewport->sizeCallbacks == 3 &&
|
||||
NSEqualSizes(viewport->publishedSize, NSMakeSize(800, 450));
|
||||
[viewport setFrameSize:NSMakeSize(640, 360)];
|
||||
hooks &= viewport->sizeCallbacks == 4 &&
|
||||
NSEqualSizes(viewport->publishedSize, NSMakeSize(640, 360));
|
||||
printf("FRAME_SIZE_HOOK callbacks=%lu published=%.0fx%.0f pass=%d\n",
|
||||
(unsigned long)viewport->sizeCallbacks, viewport->publishedSize.width,
|
||||
viewport->publishedSize.height, hooks);
|
||||
pass &= hooks;
|
||||
[viewport release]; [host release];
|
||||
[overlay release];
|
||||
[content release]; [native release];
|
||||
[child release]; [view release];
|
||||
printf("WINDOW_LAYOUT_CHECK full=%.0fx%.0f changed=%.0fx%.0f pass=%d\n",
|
||||
size.width, size.height, changed.width, changed.height, pass);
|
||||
[ordinary release]; [full release];
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"revision": "60ba801decee7a00782f74f6be4c8ffb013f79ff",
|
||||
"repository": "https://github.com/darlinghq/darling.git",
|
||||
"patch": "patches/darling.patch",
|
||||
"modified_files": 87,
|
||||
"modified_files": 88,
|
||||
"new_files": [
|
||||
"src/CoreAudio/CoreAudio/AudioConverterShim.c",
|
||||
"src/CoreAudio/AudioTrace.h",
|
||||
@@ -56,9 +56,10 @@
|
||||
"revision": "c8d38d16a9f613d300157bebbab2b9501bc0c274",
|
||||
"repository": "https://github.com/darlinghq/darling-cocotron.git",
|
||||
"patch": "patches/cocotron.patch",
|
||||
"modified_files": 103,
|
||||
"modified_files": 104,
|
||||
"new_files": [
|
||||
"QuartzCore/include/QuartzCore/CATransformLayer.h"
|
||||
"QuartzCore/include/QuartzCore/CATransformLayer.h",
|
||||
"AppKit/NSGeometryTrace.h"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user