On Oct 2, 2013, at 2:21 PM, Ken Thomases <[email protected]> wrote:

> On Oct 2, 2013, at 1:36 PM, Caylan Larson wrote:
> 
>> I am using CGWindowListCreateImage to fetch an image of the windows behind 
>> my app.  This works beautifully and is OK for my needs.  Except...
>> 
>> I have problems when I drag the window.  The goal is near real-time image 
>> updates during the drag event.
>> 
>> The runloop never seems to fully display the results of my drawRect (I can 
>> log in drawRect, but the results are not displayed).  I've tried operation 
>> queues, using mouseDragged, spinning off a thread on a window move 
>> notification using detachNewThreadSelector and looking for mouse up using 
>> nextEventMatchingMask --- all the while sending setNeedsDisplay:YES to the 
>> view or, heaven forbid, sending drawRect straight away (doesn't make a 
>> difference).  I've made sure "Can Draw Concurrently" is checked at every 
>> level as well as the window setting for allowsConcurrentViewDrawing.
>> 
>> My next step was to ditch drawRect and instead use an embedded imageView in 
>> a scrollView.  In windowWillMove I stuff the whole screen's image in the 
>> imageView and then scrollPoint to the window's frame origin.  This still 
>> doesn't get me real-time scrolling of the scrollView when the window is 
>> dragged.
>> 
>> My hunch is that the window drag event makes the runloop run in 
>> NSEventTrackingRunLoopMode, which limits drawRect's efficacy.  Any way 
>> around this condition?
> 
> First, unless you call [yourWindow setMovable:NO], moves are largely handled 
> in the window server with only occasional notifications to your app that the 
> frame has changed.  If you do call that, then you have to handle clicks and 
> drags in the window frame by overriding -[NSWindow sendEvent:] and processing 
> the appropriate events.  It's non-trivial, but at least you have full control.
> 
> Second, when the framework (or anything) runs an internal run loop, you can't 
> rely on the windows being updated.  You can try calling -displayIfNeeded 
> and/or -flushWindow.
> 
> Third, I doubt you're going to get real-time performance out of the CGWindow 
> API.  Apple recommends using the AV Foundation for that:
> Technical Q&A QA1740: How to capture screen activity to a movie file using AV 
> Foundation on Mac OS X Lion
> https://developer.apple.com/library/mac/qa/qa1740/_index.html
> 
> The AVScreenShack sample code may also be useful:
> https://developer.apple.com/library/mac/samplecode/AVScreenShack/Introduction/Intro.html

I looked at the AV Foundation docs and it seems like there is not a way to get 
a screenshot without my window (like kCGWindowSharingNone).  There seems to be 
a serious problem in CGWindowListCreateImage when called too frequently.

From the user's POV, the UI freezes until I "kill -9" via SSH.  The recovery 
looks like:

Oct  6 12:22:38 Caylans-MacBook-Pro.local WindowServer[100]: CGXDisableUpdate: 
UI updates were forcibly disabled by application "Xcode" for over 1.00 seconds. 
Server has re-enabled them.
Oct  6 12:22:38 Caylans-MacBook-Pro.local WindowServer[100]: 
reenable_update_for_connection: UI updates were finally reenabled by 
application "Xcode" after 160.03 seconds (server forcibly re-enabled them after 
160.02 seconds)

Someone told me that this could be due to calls to CGXDisableUpdate without a 
balanced CGXEnableUpdate.  What is the best way to squeeze performance out of 
CGWindowListCreateImage without getting hosed/throttled by WindowServer?  Or is 
this a race condition that is beyond my reach?

Help :-)

Caylan


_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to