views:

43

answers:

1

I am new to the Mac world and am seeing some behavior that is puzzling to me. I am working on a basic full screen utility that will capture the main display of the Mac and display some text. The problem I am having is that if I capture the display multiple times, after the first time the text that I am writing the the contextRef begins to degrade at the beginning of the line each time it is written. The first time it might be that the fill doesn't get drawn in the first letter, after that whole sections of the text at the beginning of the line disappear. The code I am using is as follows:

CGDisplayCapture(kCGDirectMainDisplay);
CGDirectDisplayID display = kCGDirectMainDisplay;
CGContextRef ctx = CGDisplayGetDrawingContext (display);

CGContextSelectFont (ctx, "Times-Roman", 48, kCGEncodingMacRoman);
CGContextSetTextDrawingMode (ctx, kCGTextFillStroke);
CGContextSetRGBFillColor (ctx, 1, 1, 1, 0.75);
CGContextSetRGBStrokeColor (ctx, 1, 1, 1, 0.75);
CGContextShowTextAtPoint (ctx, 400, 400, text, strlen(text));   

I have found that if I put a '[NSThread sleepForTimeInterval:0.25]' before the CGContextShowTextAtPoint that the text would always display properly but that is what I would consider a hack.

My question for those who are smarter then I is, what is going on to cause the problem and is there something different that I should be doing to try and resolve it?

TIA,

JT

+1  A: 

To make a basic full screen app, do not get the CGDisplay and associated CGContextRef and directly draw on it. I guess you're drawing to the context without being notified by the system to do so at all. That's not what you are supposed to do.

Unless absolutely necessary, create a big view which covers the entire screen, (i.e. keeping windows of other applications behind,) and draw on it just as you would do to a normal view. I.e. never get the context manually and write it actively. Rather, implement a subclass of NSView, implement drawRect, and perform the drawing inside. Finally, use enterFullScreenMode:withOptions: to make the view full screen.

Yuji
Part of the projects requirement is that for the short time the text is displayed that the user cannot do anything else. That is why I am capturing the screen. If that were not a requirement I would do as you suggest. I did test using using a NSGraphicsContext and NSString drawAtPoint. This also allowed me to write the text out but it also displayed the same issue when drawing multiple times in succession.Could I add a NSView to the NSGraphicsContext and then draw the text to that?
Even with that requirement, what you should do is to create an `NSView` which has a possibly transparent background covering all the display, so that it captures every event. `enterFullScreenMode:withOptions` does that. It's not that you draw to the context at whichever time you wish; instead, the system calls your `-drawRect` whenever the system feels right. If you draw to the context outside that, something bad happens.
Yuji
Thanks Yuji, I'll give it a try and see how it works and let you know.