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]
