Process injected mouse events#8459
Conversation
feerrenrut
left a comment
There was a problem hiding this comment.
I'm a little worried about the robustness of this approach.
| @contextmanager | ||
| def ignoreInjection(): | ||
| """Context manager that allows ignoring injected keys temporarily by using a with statement.""" | ||
| global ignoreInjected |
There was a problem hiding this comment.
This won't be thread safe. If multiple threads use this context manager at once, the value of ignoreInjected could be squashed.
|
|
||
| # Translators: This is the label for a checkbox in the | ||
| # mouse settings panel. | ||
| handleInjectedMouseControlText = _("Handle mouse control from other &applications") |
There was a problem hiding this comment.
I don't think the naming of this setting conveys what it does. Maybe something like "Ignore mouse movement triggered by other applications"
There was a problem hiding this comment.
I started with the word movement, but the problem with that word is that strictly spoken, mouse clicks aren't movement either.
There was a problem hiding this comment.
I was more concerned with the word "handle". Though "mouse control" doesn't quite sound right to me either. Perhaps "Ignore mouse input from other applications"?
There was a problem hiding this comment.
Hmm, ignore mouse input would turn the boolean upside down and causes a symmetrical conflict with handle keys from other applications in the keyboard settings.
How about "Process mouse input from other applications"
There was a problem hiding this comment.
After considering this a little more, I think that I agree now with the wording using "ignore" now. May be it makes sense to reword the keyboard settings option as well?
| # Import late to avoid circular import | ||
| import mouseHandler | ||
| with mouseHandler.ignoreInjection(): | ||
| return user32.mouse_event(*args) |
There was a problem hiding this comment.
I don't think that we can rely on the timing of receiving these events. Currently this design relies on the events being received while this contextManager is active.
There was a problem hiding this comment.
Hmmmm, a similar approach is used in keyboardHandler.KeyboardInputGesture.send, though there, wx.Yield is called before closing the context manager.
There was a problem hiding this comment.
I have a feeling that code relies on a sleep, which I'm not a fan of either! Really we need a way to identify that a future received event is the one we planned to ignore, and only ignore that one.
There was a problem hiding this comment.
Hmm yes, this could be a cause of #8020.
Note that similar to wx.Yield, we also have wx.YieldIfNeeded.
I"m still not sure what to do here. @michaelDCurran or @jcsteh, thoughts?
There was a problem hiding this comment.
I discovered that there's also wx.GetApp().SafeYieldFor which allows a bitmask of events to be provided, limiting the yield to whatever events you provide.
Regarding SafeYield:
This function is similar to wx.Yield , except that it disables the user input to all program windows before calling wx.AppConsole.Yield and re-enables it again afterwards.
|
@josephsl: Could you elaborate on differences between WX Python 3 and 4 regarding wx.Yield? This code depends on wx.Yield, so it might make sense to change this as part of this pr at least in this area of the code. |
|
Hi, last time I checked, wx.Yield in wxPython 4 calls wx.AppConsole.Yield. I, @jcsteh, and wxPython developer had a discussion about this a while back. Thanks.
From: Leonard de Ruijter <notifications@github.com>
Sent: Monday, July 30, 2018 11:13 AM
To: nvaccess/nvda <nvda@noreply.github.com>
Cc: Joseph Lee <joseph.lee22590@gmail.com>; Mention <mention@noreply.github.com>
Subject: Re: [nvaccess/nvda] Process injected mouse events (#8459)
@josephsl <https://github.com/josephsl> : Could you elaborate on differences between WX Python 3 and 4 regarding wx.Yield? This code depends on wx.Yield, so it might make sense to change this as part of this pr at least in this area of the code.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#8459 (comment)> , or mute the thread <https://github.com/notifications/unsubscribe-auth/AHgLkPfL3Uzr_hIqBQiIsoyw5pfpjDDbks5uL0zJgaJpZM4U7XRW> .
|
|
It might make sense to implement #8679 as part of this pr. |
|
@feerrenrut: I'm a bit unsure as what to do to make this pr to a success now. I and others would really appreciate this being included in a next release of NVDA> |
|
I can look into this.
|
michaelDCurran
left a comment
There was a problem hiding this comment.
KeyboardInputGesture.send requires a sleep and wx.yield because we want to guarantee that by the time that send returns, the keyboard input generated has been injected and NVDA has received and processed it. As we do not have scripts for mouse input currently, this is not relevant for the mouse.
From what I can read on msdn, low-level keyboard hooks will be run within the call to keybd_event, so to low-level mouse hooks will be run within mouse_event. Thus we can guarantee that the related ignore input variable we are setting with the context manager will be correct when the hooks run.
Perhaps we should look into replacing wx.yield in keyboardHandler, but I feel this is not something for this pr.
In short, once the other review actions in my review here are addressed, I am happy to approve this.
| audioCoordinates_minPitch = integer(default=220) | ||
| audioCoordinates_maxPitch = integer(default=880) | ||
| reportMouseShapeChanges = boolean(default=false) | ||
| ignoreINjectedMouseInput = boolean(default=false) |
There was a problem hiding this comment.
Should not be a capital N in INjected.
|
|
||
| # Translators: This is the label for a checkbox in the | ||
| # mouse settings panel. | ||
| ignoreINjectedMouseInputText = _("Ignore mouse input from other &applications") |
There was a problem hiding this comment.
Again INjected should not have capital N
| # mouse settings panel. | ||
| ignoreINjectedMouseInputText = _("Ignore mouse input from other &applications") | ||
| self.ignoreINjectedMouseInputCheckBox=sHelper.addItem(wx.CheckBox(self,label=ignoreINjectedMouseInputText)) | ||
| self.ignoreINjectedMouseInputCheckBox.SetValue(config.conf["mouse"]["ignoreINjectedMouseInput"]) |
There was a problem hiding this comment.
Okay, looks like a bad find and replace ;)
| # #8452: NVDA should ignore mouse events that are injected by itself. | ||
| # Import late to avoid circular import | ||
| import mouseHandler | ||
| with mouseHandler.ignoreInjection(): |
There was a problem hiding this comment.
I do not like NVDA specific state being affected in winUser. winUser should really just be a module that pythonizes win32 APIs. Rather add a wrapper function in mouseHandler or a new mouseUtils module or something.
There was a problem hiding this comment.
Valid point there. It required some changes to get this right, though.
|
@LeonarddeR Are you happy for this to be merged to master now? |
|
Sure!
|
Link to issue number:
Closes #8452
Fixes #7480
Summary of the issue:
NVDA silently ignores mouse events that are injected by third party applications, particularly remote control software such as TeamViewer. When mouse tracking is enabled, NVDA does not announce what is under the mouse when a TeamViewer partner is controlling it.
Description of how this pull request fixes the issue:
Testing performed:
Tested injected mouse events by having a colleague control my system remotely via TeamViewer. His mouse movement was announced by NVDA.
Known issues with pull request:
Mouse movement caused by SetCursorPos, which is strictly spoken only moving the mouse cursor, is still ignored by NVDA. We probably have to hook SetCursorPos if we want to support this, but I don't think that this is relevant. IN any case, it falls outside the scope of this pr.
Change log entry: