Fix build on current GNUstep and CALayer struct-property KVO crash#8
Fix build on current GNUstep and CALayer struct-property KVO crash#8pkgdemon wants to merge 2 commits into
Conversation
|
Note this depends on gnustep/libs-opal#16 |
|
@gcasa Here are fixes discussed in last GNUstep meeting. |
|
@ivucica Let me know if this is something you might want, or if you foresee the need for a lot of changes. I did get libs-opal fixes merged so this will build now. |
|
@ivucica Also something else from the readme I am not sure this is the case anymore: Patched Opal. Opal currently conflicts with AppKit. More specifically, it also implements an incompatible NSFont. An experimental patch is provided against r35173 of Opal in opal-nsfonthacks.patch. At least with my PR the demo app works fine, and no other patches required. |
ivucica
left a comment
There was a problem hiding this comment.
- Generally good, except for some confusing codeblock removals and use of forloop where an NSSet would make more sense. Also: fixing GNUstep-specific codepaths should also be marked as GNUstep-specific; there's a decent reason why this should run under macOS (or at least the 13yo versions of it that I was developing this with); checking if a demo behaves the same way natively vs with alt implementation is easier if I don't need a shared directory mounted on two machines (one macOS, one Linux) and can simply use two different build targets on macOS to compare behavior1.
- In future, I'd mainly like seeing fixes split up in multiple PRs independently reviewable. Similarly: bugfix != cleanup != reformatting, and of course != feature work, so (where reasonably possible) it's good to split this up into multiple commits and PRs for reviewability etc.
Footnotes
-
Comparing behavior strictly for compatibility work, of course. ↩
| { | ||
| ApplicationDescription = "Demonstration of GNUstep QuartzCore"; | ||
| ApplicationName = GSQuartzCoreDemo; | ||
| ApplicationName = QuartzCoreDemo; |
There was a problem hiding this comment.
I have a slight preference for not mixing this change in :)
| [_renderer setLayer: layer]; | ||
| [layer setBounds: NSRectToCGRect([self bounds])]; | ||
| [layer setBackgroundColor: whiteColor]; | ||
| [layer setBackgroundColor: whiteColor]; |
There was a problem hiding this comment.
I will accept this, but for the future, I prefer not mixing style changes or cleanup in the same commit or PR as improvements (and same for mixing bugfixes in the same PR as improvements or as cleanups).
| @implementation AppController | ||
| -(void)applicationDidFinishLaunching: (NSNotification*)aNote | ||
| { | ||
| #if GNUSTEP |
There was a problem hiding this comment.
Why remove this? It's a replacement for a missing .nib / .xib / gorm file. Unless it breaks the build, let's remove this in a separate PR.
There was a problem hiding this comment.
This was a few months ago, and no longer fresh in my mind. I will revert back some of these changes locally to see if it did break the build or not, and report back findings.
| already emit willChange/didChange notifications directly. */ | ||
| static NSString * structKeys[] = { | ||
| @"anchorPoint", @"transform", @"sublayerTransform", | ||
| @"contentsRect", @"shadowOffset", @"bounds", @"position" }; |
There was a problem hiding this comment.
We should keep the two lists in sync. Please move this static ... structKeys out to live just next to GSCA_OBSERVABLE_SETTER definition for clarity (and rename it).
Next, this should be an NSSet or similar, for faster lookup. I'll leave a similar comment below.
Next, GSCA_OBSERVABLE_SETTER and that entire part is #if GNUSTEP just like this should be; when built on macOS, this part should not apply.
| [_observedKeyPaths addObject: keys[i]]; | ||
| /* Set up KVO observation for non-struct properties only */ | ||
| BOOL isStructKey = NO; | ||
| for (int j = 0; j < sizeof(structKeys)/sizeof(structKeys[0]); j++) |
There was a problem hiding this comment.
Needlessly introducing O(i*j) 1; this should be a map/dict or set lookup instead of a for loop (even if the loop is really, really short and probably unrollable by the compiler).
This should also be a GNUstep only bit (#if GNUSTEP). With macOS, all keys should be KVObserved.
Perhaps this does not require a static list of struct keys (and, in fact, might break for user-provided animatable properties, which this implementation can support via @dynamic) -- you could query the runtime.
Footnotes
-
O notation being 'worst-case', not 'average case' ↩
| context: nil]; | ||
| [_observedKeyPaths addObject: keys[i]]; | ||
| NS_HANDLER | ||
| /* Some property types (e.g. CGColorRef) may not support |
There was a problem hiding this comment.
I don't like exception handling here. Especially with current implementation that lists supported properties explicitly in the keys variable. If addObserver doesn't like it, we should not blindly ignore it; at the VERY LEAST we should log a warning that something went wrong. Please add at least an NSLog() or equivalent statement. Otherwise, remove the exception handling until we have a need to observe more than keys[i].
| # This file should be autogenerated from config.make.in. | ||
| # However, we have no need for "configure" script yet. |
There was a problem hiding this comment.
Cleanup unrelated to actual fixes, so this should be a separate commit and even a PR. But I will accept it here.
| @@ -0,0 +1,9 @@ | |||
| # Build artifacts | |||
There was a problem hiding this comment.
Cleanup unrelated to actual fixes, so this should be a separate commit and even a PR. But I will accept it here.
|
|
||
| QuartzCore_OBJCFLAGS += $(WARN_FLAGS) | ||
| # Newer clang treats -Wint-conversion as a hard error; suppress for | ||
| # CoreFoundation.h compatibility shim which has type mismatches in |
There was a problem hiding this comment.
I have no problem merging this, but should we fix this instead? Is the CoreFoundation.h you speak of in libs-corebase and should that be addressed there? A reference to an issue filed via either Savannah or Github would be great, if fixing there would be appropriate.
(Optional, I don't really want to add too much unnecessary work.)
|
Sorry for the delay. I'm very glad about the issues identified. I wish I wrote cleaner unit and integration tests that can run headless, but it is what it is. |
Thanks @ivucica it will take me some time to refresh this with the requested changes. But I can get it done and try to back out some of the changes we may not have needed to get the minimum viable fixes to fix the building, runtime issues. I will try to have something ready ASAP by the end of the week. |
| #endif | ||
| #if (__APPLE__) | ||
| #define GL_GLEXT_PROTOTYPES 1 | ||
| #if (__APPLE__) |
There was a problem hiding this comment.
Mostly done as part of merging a variant of PR #7 so during rebase this can be removed. (Import of GL/glext.h is only needed if you also #define GL_GLEXT_LEGACY, see /usr/include/GL/gl.h - in my case, I inspected the one from Debian bookworm from libgl-dev 1.6.0-1).
|
@pkgdemon No need to hurry, and feel free to push back if something is too large of a request. You can also stack new commits with fixes and just tell me to squash it all at the end. |
Yes I think part of the reason this was so large is that I combined both build and runtime fixes to make all of the tests work on GNUstep. I did get some other fixes into libs-opal, libs-corebase merged. I'll start fresh and see what was absolutely necessary a little later this week. |
Summary
Two related changes so libs-quartzcore builds and the bundled demo
actually runs on current GNUstep/Linux:
current generation of GNUstep core (Foundation/CoreFoundation) and
against a non-Apple OpenGL.
(
bounds,position,anchorPoint,transform,sublayerTransform,contentsRect,shadowOffset) can no longer be registered forautomatic KVO observation on GNUstep — the autogenerated setter
overrides corrupt struct arguments passed by value through
objc_msgSend. The demo app crashed on startup before this.Build changes (
da7275a)Headers/QuartzCore/CABase.h— importFoundation/NSObject.hbeforeCoreFoundation.hso CF inline functions can resolve-hash/-isEqual:signatures. (Same pattern libs-opal needs on currentGNUstep.)
Headers/QuartzCore/CATransaction.h— switch from#import "CoreFoundation/CFDate.h"to#import <CoreFoundation/CoreFoundation.h>. The quoted per-headerpath doesn't resolve reliably against libs-corebase install layout.
Source/CABackingStore.h— move#define GL_GLEXT_PROTOTYPES 1outside the Apple-only block so non-Apple builds also get it, and
add
#import <GL/glext.h>for the non-Apple path.Source/GNUmakefile/config.make— minor flag adjustments forthe current toolchain.
.gitignore— ignoreobj/,derived_src/,*.framework/,*.app/.CALayer fix (
2ae02bb)CALayer -initused to register every property in its defaults listfor KVO observation via
CAImplicitAnimationObserver. On GNUstep thisworks for object-typed properties but breaks for struct-typed ones:
the KVO machinery generates a setter override that receives the struct
by value through
objc_msgSend, and on GNUstep the argument marshallingcorrupts the struct contents. Setting
bounds/position/etc. on afresh layer would then either crash or write garbage.
Changes in
Source/CALayer.m:structKeyslist:anchorPoint,transform,sublayerTransform,contentsRect,shadowOffset,bounds,position. These are excluded fromaddObserver:forKeyPath:.Their setters already emit willChange/didChange via
GSCA_OBSERVABLE_SETTER/ the manual-setBounds:/-setPosition:,so implicit animations still fire.
transformandsublayerTransformanalogous to the existing
shadowOffsetspecial-case: try KVC first,fall back to the typed setter inside NS_DURING / NS_HANDLER.
addObserver:in NS_DURING / NS_HANDLERso property types that don't support automatic KVO (e.g.
CGColorRef)don't abort
-init.#if 0debug block.Demo changes (
2ae02bb)Demo/AppController.m— remove the hand-rolledNSMenucreationunder
#if GNUSTEP. The main menu is already provided through thestandard GNUstep app loading path; the duplicate menu setup was a
leftover.
GSQuartzCoreDemo→QuartzCoreDemoin the Info.plist(
ApplicationName,NSExecutable) to match the current bundle name.DemoOpenGLView.m.Compatibility
additive to the existing Apple code paths.
through
<CoreFoundation/CoreFoundation.h>as expected.Testing
libs-corebase, libs-opal) on Devuan/Linux x86_64.
Demo/QuartzCore demo launches, the CALayer tree iscreated without crashing, and the root layer renders through the
GL view.