-
-
Notifications
You must be signed in to change notification settings - Fork 651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check screen is black after activating screen curtain #12701
base: master
Are you sure you want to change the base?
Conversation
@@ -300,6 +300,43 @@ def confirmInitWithUser(self) -> bool: | |||
return res == wx.YES | |||
|
|||
|
|||
def isScreenFullyBlack() -> bool: | |||
""" | |||
Uses wx to check that the screen is currently fully black by taking a screen capture and checking: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have you considered using the screenBitmap module for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved the implementation to use that instead, thanks for highlighting this as an option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having to iterate over this bitmap in python was considerably slower (took 4s on my machine). Using the wx method to calculate the histogram in native code takes 0.4s comparably.
b7692c5
to
5f756a4
Compare
Using complete black as the screen curtain color makes it hard to differentiate from a failed buffer grab (initialized to zero). Perhaps, this would be safer to transform the screen to a slightly off-black, and test for that color. |
Should this be done in another PR? I imagine this may be contentious with problems like screen burn in and OLED power saving. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@feerrenrut |
bmp: wx.Bitmap = wx.Bitmap(screenSize[0], screenSize[1]) | ||
mem = wx.MemoryDC(bmp) | ||
mem.Blit(0, 0, screenSize[0], screenSize[1], screen, 0, 0) # copy screen over to bmp | ||
del mem # Release bitmap | ||
img: wx.Image = bmp.ConvertToImage() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@feerrenrut - at what stage is a buffer grab fail a concern?
Would a check like the following be an improvement?
Where setCanaryBits
sets the bmp
to some non-zero value canaryBits
.
And areCanaryBitsSet
checks if the bits are still set in the memory.
bmp: wx.Bitmap = wx.Bitmap(screenSize[0], screenSize[1]) | |
mem = wx.MemoryDC(bmp) | |
mem.Blit(0, 0, screenSize[0], screenSize[1], screen, 0, 0) # copy screen over to bmp | |
del mem # Release bitmap | |
img: wx.Image = bmp.ConvertToImage() | |
bmp: wx.Bitmap = wx.Bitmap(screenSize[0], screenSize[1]) | |
setCanaryBits(bmp, canaryBits) | |
mem = wx.MemoryDC(bmp) | |
assert areCanaryBitsSet(mem, canaryBits) | |
mem.Blit(0, 0, screenSize[0], screenSize[1], screen, 0, 0) # copy screen over to bmp | |
assert not areCanaryBitsSet(mem, canaryBits) | |
del mem # Release bitmap | |
img: wx.Image = bmp.ConvertToImage() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: This doesn't handle if screen
is initialised wrong - which is handled by wx
and we have little control over.
That's one failure we are aware of, but there are quite likely other ways that this could fail that we aren't aware of. The feature should let users rely on it, so they don't need sighted assistance to confirm that screen curtain is working.
I don't think we could reliably guarantee this, even if we tested on all Windows versions (and updates) there may be other ways this could fail. Perhaps bad video drivers, or antivirus software. Because this is privacy related, the feature should err on the side of caution. |
I think it should take multiple approaches:
To maintain performance it might be required to do this from C++ and asynchronously. |
Link to issue number:
Fixes #12708
Summary of the issue:
There is a security risk if the screen curtain fails silently. The Magnification API used by Screen Curtain does not officially support WOW64 applications like NVDA. As this is a risk with untested Windows versions, an external check would be helpful to minimise silent failures of the screen curtain.
Description of how this pull request fixes the issue:
Capture the screen and check it is fully black after initialising screen curtain.
wxWidgets uses winGDI methods, winGDI is a low level, stable API, as compared to the Magnification API:
wxScreenDC captures all monitors.
Testing strategy:
Manual confirmation from a sighted developer is required.
Example for Win 10:
Example for Win 11 (preview):
Known issues with pull request:
None
Change log entries:
None
Code Review Checklist: