CGContextSetCompositeOperation error for some users when drawing NSWindow - cocoa

A simple 10.6 Cocoa app I wrote that basically draws a regular window with some buttons and text has been spewing hundreds of console log messages:
<Error>: CGContextSetCompositeOperation: invalid context 0x0
I do not directly call drawRect: and always use setNeedsDisplay:YES when I need to refresh.
Interestingly, this error does not happen on all machines, I'd say about 50% get the error. However, the program works fine in either case!
Anyone got any clue as to what this error means, where it's stemming from, and more importantly, how can I suppress/get rid of it?
Thanks

Try setting a breakpoint on CGPostError. If you can break on the logging, you can hopefully figure out what's going on.
You shouldn't be looking to just suppress it. It means context creation is failing (thus NULL gets passed for some context parameter), and that's not good.

Related

Assertion error when using NSCollectionView with QLPreviewView

I am using an NSCollectionView where each NSCollectionViewItem uses a QLPreviewView to get a rendering of a file's content.
(This is an attempt at a file browser for images and other previewable files.)
Initially, this works fine.
However, once collection items are getting re-used, I get an assertion error (both in 10.13 and 10.14):
[QL] Assertion failure (unreachable code) - [… MyPreviewView activated … doc:[QLPreviewDocument …]] is already activated
Apparently, before I can re-use a NSCollectionViewItem, the previously used QLPreviewItem needs to be set to inactive state somehow. How do I do that?
I've tried to send the close message to the QLPreviewView instance but that doesn't make a difference.
I also do not get a dealloc call on my QLPreviewView subclass, which suggests that the object is still referenced by something else, possibly the QLPreviewDocument, which then gets confused about the change of state.
I have made a demo project available on github: https://github.com/tempelmann/NSCollectionViewWithQLPreview
To test: Run it, then scroll down. When reaching items 50 to 60, the assertion will be triggered.
The fix is to set QLPrewiewView's shouldCloseWithWindow property to NO.
This, I suspect, tells the controller behind the scenes not to attach itself to higher level structures, i.e. tells it to remain self-sufficient.
So, adding this line to the code that sets up a new MyPrewiewView object in the sample code's ViewController.m file prevents the error:
qlView.shouldCloseWithWindow = NO;

Delphi TForm OnCreate gets called multiple times

I hope I can explain this problem decently well!
I'm trying to implement a ReWire audio device as a Delphi .dll. If you don't know what ReWire is, don't worry about it. What's important is that my code compiles into a .dll, and I get calls from the ReWire system into my .dll to open up a display, check if the display is opened, and close it again.
When I get the call to launch, I do the following:
if not Assigned(form) then
form := TMyForm.Create(nil);
form.Show;
where form is a global variable inside of my Delphi library (maybe a problem?). I have hooked up MyForm's OnCreate event to do some interesting things like prepare an array of stuff I want to work with.
So far everything's good. My form has a little button in it that opens up a TOpenDialog. I find that as soon as that dialog closes, somehow the OnCreate event is firing again in my form!
I have checked that OnDestroy is not being called, so I have no idea why OnCreate is getting called again.
Unfortunately I'm not really sure what information is relevant, but here's the call stack the first time around (when the form is first set up):
As expected, ReWire is making a call into my .dll to Launch the Panel application, so I create my form. Great, things are looking good.
Then inside my form, I open up a little dialog, select a file, and do some operations. Out of left field, OnCreate is called again, and here's the call stack that time:
It's a crazy party of calls! Reaper (at the bottom) is the ReWire host I'm using to test my application, but I have no idea what's going on inside that stack trace because none of it is my code. Suddenly the event just gets called when I don't think it should, because OnDestroy wasn't even called.
The only other important thing I can think of is that if I print out the address of the Sender, it's different each time, so it's somehow getting Created again or something, but I've checked that I only call the MyForm.Create once.
Any ideas as to how this type of thing could happen?
In the first stack trace, the OnCreate call is preceded by a call to TCustomForm.Create(), which is correct behavior. In the second stack trace, the OnCreate call is preceded by a call to TObject.Create() instead, which is not correct behavior. That leads me to think that something in your button OnClick event handler is either constructing an object with a bad VMT, or is otherwise corrupting memory in general and causing a bad jump into code that just happens to be occupied by your TForm class. Either way, double check your OnClick logic for bugs.
Check on (any)where you are setting the form variable to nil. It may be that it's being set to nil without freeing the form it's pointing to, and so next time your launch code is called it's creating another instance of the form.

What will prevent LVN_ITEMACTIVATE from firing?

I am writing an app with raw windows API (opensource Win32++) where I have a ListView.
The problem I have now is that whenever an item in the ListView is clicked, the system/app will generate a warning tone/sound "ding". Furthermore, I noticed I cannot get the LVN_ITEMACTIVATE through item-dbl-click or item-keypress-enter, which would normally work if this problem had not occur.
Would anyone have any idea how this might be happening?
I believe there is nothing wrong with Win32++, it just could be one of the things I do is causing this. But my program has become quite big to dissect plus I have no idea where to start looking.
Thanks.
PS: I had my computer muted for the longest time, hence, I don't know when this started eventhough I had the listview since a long time ago. T_T
Start looking with a tool that can show you the Windows messages that the control generates and receives. Like Microsoft's Spy++. Compare it with a working list view to have an idea what might be amiss. Also check the parent window. I haven't otherwise heard of listviews that dingaling, the LVN_ACTIVATEITEM should fire the first WM_LBUTTONDOWN, no double-click necessary.

Cocoa NSOutlineView bug - [NSCFTimer copyWithZone:]: unrecognized selector sent to instance

I'm using an NSOutlineView with the function
- (BOOL)outlineView:(NSOutlineView *)outlineView
isGroupItem:(id)item
defined so it gives the group row GUI look. When I add a root item, it works fine. When I add an item to root's child array and expand it, it works fine. If I contract the item though, the following error is logged:
[NSCFTimer copyWithZone:]: unrecognized selector sent to instance
I also get an EXC_BAD_ACCESS error if the app window is deactivated by switching to another app. I used the debugger to try to find where I might have made an error in one of my functions, but the stack trace only shows functions I did not create (RunCurrentEventLoopInMode, CFRunLoopRunSpecific, handleWindowNeedsDisplay, etc.) Does anyone have any idea where my error(s) might be?
Sounds like an object is dying prematurely. You get the “unrecognized selector sent to instance” exception when a new object is allocated later with the same pointer and then something tries to send the old object a message (in the example shown, the reincarnation is an NSTimer and the message something tried to send the previous object was copyWithZone:). You get an EXC_BAD_ACCESS crash when the object is simply garbage memory.
Debug this by running your app under Instruments with the Zombies instrument enabled. The object will, instead of dying, become a zombie object. When something tries to send a zombie a message, the zombie will moan (figuratively speaking), which will show up in Instruments's timeline as a flag. You can click a button in that flag to view the history of the object, including all of its retentions and releases.

RBSplitView has delayed reload of autosaved view positions

I really enjoy using RBSplitView, an open source replacement for NSSplitView, but I have a problem in my shipping app and am experiencing it again in a new project.
The problem is I'm telling the RBSplitView to autosave its position state by giving it an autosave name. When my app launches the RBSplitView doesn't seem to honor the saved state till a second after the window is drawn.
I've spent the night trying to debug the behavior but have had little success. Anyone out there use this lib and have some advice?
You can scrub this quicktime movie to the issue at work:
http://media.clickablebliss.com/billable/interface_experiments/rbsplitview_delayed_autosave_reload2.mov
I've still been unable to figure out why this is happening but I do have a workaround.
First, make sure your main window is not visible at launch and then at the end of applicationDidFinishLaunching in your app delegate add something like:
[mainWindow performSelector:#selector(makeKeyAndOrderFront:) withObject:self afterDelay: 0.1];
The delay is the key. If you just tell the window to makeKeyAndOrderFront: I still see the issue. However as long as it has a beat of time it looks good.
This likely is happening because the RBSplitView instance needs to wait until it's first moment to get to set its frame to the autosaved value, which happens to be after the user can see it. This 0.0-delay trick simply delays showing the window until the very next runloop, which gives the split view a chance to do its magic (and other views) so that when the user sees the window, it's already nice and sexy. So just do the delay at 0.0 and you'll be fine.
I have a similar, but slightly different workaround in my app that uses RBSplitView. In applicationDidFinishLaunching:, I call adjustSubviews on the split view before calling makeKeyAndOrderFront: on the window that contains it. This seems to knock the split view in to order before it gets displayed on the screen.

Resources