Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does kCGWindowSharingState actually do?

If you call CGWindowListCopyWindowInfo(), the CFDictionaryRef that you get back contains a number of keys and values. One of these is kCGWindowSharingState, which has three possible values:

Window Sharing Constants
Specifies whether and how windows are shared between applications.

enum {
   kCGWindowSharingNone      = 0,
   kCGWindowSharingReadOnly  = 1,
   kCGWindowSharingReadWrite = 2
};

Nearly all of the windows on my system are kCGWindowSharingReadOnly, and the SonOfGrab screen-shot sample program avoids trying to capture kCGWindowSharingNone windows, but I couldn't find a good description of what those states are intended to be used for.

A simple test seems to show that several of the apps that come with OS X do have windows that are set to kCGWindowSharingNone, in particular Notes and iBooks. As far as I could tell from a quick test, having the window set to kCGWindowSharingNone doesn't actually prevent CGWindowListCreateImage() from capturing an image of that window. There are no windows that I was able to find that have kCGWindowSharingReadWrite set as their sharing mode.

Is all of this explained somewhere in the documentation, and I just missed it, or is it just more barely-documented Core Graphics functionality? Is there a good reason to not try to capture kCGWindowSharingNone windows, and will I be setting myself up for trouble in the future if I try to do so?


Further investigation has shown that when a Cocoa app calls

[NSWindow setSharingType:]

That sets kCGWindowSharingStateNone on the window, and prevents it from being captured by CGWindowListCreateImage(). There also some other windows that have kCGWindowSharingStateNone set, but which can be successfully captured - in particular, iBooks creates a window like this.

This is presumably a bug in iBooks, or in whatever API it's calling (since it doesn't call the NSWindow API).

like image 820
Mark Bessey Avatar asked Dec 29 '14 20:12

Mark Bessey


1 Answers

If you're going to ignore a window's sharing state you should be prepared to have some windows behave just as the API specifies and, apparently according to your own research, some not.

Higher up in the Cocoa APIs, NSWindow has a sharingType property. Setting that to NSWindowSharingTypeNone makes the corresponding CGWindow have a sharing type of kCGWindowSharingNone.

When I change this property on a window in my own application, it does prevent other applications from using the CGWindow API to capture the window’s contents. The documentation for CGWindowListCreateImage seems to also be correct.

Any windows that are onscreen but whose sharing setting is set to kCGWindowSharingNone are skipped and not included in the resulting image.

When I take a multi-window screenshot that should include the private window, that window is missing from the screenshot.


A reason one might do this in your own application is to prevent graphical content from being copied out.

I don’t know why iBooks and Notes exhibit the behavior you describe. I could imagine Apple not wanting a user to be able to copy content from an iBook, but that's clearly not happening, and doesn't make sense for Notes (incidentally, Notes' window seems to be normal in 10.10.2).

I am not aware of any way to take advantage of the read/write type for a window’s content.

like image 91
Fabian Avatar answered Oct 23 '22 05:10

Fabian