Skip to content

Remove RTL and LTR marks from taskbar clock text and from edit boxes in a properties window#8643

Merged
feerrenrut merged 13 commits into
nvaccess:masterfrom
lukaszgo1:I8361
Mar 27, 2019
Merged

Remove RTL and LTR marks from taskbar clock text and from edit boxes in a properties window#8643
feerrenrut merged 13 commits into
nvaccess:masterfrom
lukaszgo1:I8361

Conversation

@lukaszgo1

@lukaszgo1 lukaszgo1 commented Aug 17, 2018

Copy link
Copy Markdown
Contributor

Link to issue number:

Fixes #8361

Summary of the issue:

Right-to-left and left-to-right characters In the taskbar clock and in the read-only edit boxes in a properties window was annoying when reading character by character, or when displayed on a braille display.

Description of how this pull request fixes the issue:

The characters are removed from clock name and value, from read-only edit boxes in Windows Explorer,, and from read-only edit boxes in dllhost, which is responsible for displaying properties window under older builds of Windows 10.

Testing performed:

Tested as follows on Windows versions from Win 7 to the latest insider build with a braille display connected:

  1. Moved to the clock icon in the system tray
  2. Ensured that the role and value are reported only once to avoid double announcement of clock icon in the system tray #4364 again.
  3. With the review cursor moved character by character to ensure that RTL and LTR marks are gone from the clock text.
  4. Opened properties window for a folder or file, moved with the object navigation to the modified edit box, and ensured that the RTL and LTR marks are no longer present.

The test build was also tested by @DrSooom, and he also confirms, that the issue is fixed.

Known issues with pull request:

  1. I’ve removed Right-to-left character from the clock, however I haven’t seen it there. Removing it doesn’t hurt, and for right-to-left languages it might be present.
  2. The RTL and LTR marks are defined three times in the code. It will be nice to clean this up, but I have no idea where to place them to avoid this duplication.

Change log entry:

The removal from the clock icon was covered by #5729 so only remaining thing is

Section: Bug fixes

NVDA no longer reports (LTR and RTL marks) in Braille or per-character speech when accessing the properties window.

Remove from clock name and value, read-only edit boxes in the properties window
Add an app module for dllhost, which is used to remove those characters from properties window on older Windows 10 builds.
@lukaszgo1

Copy link
Copy Markdown
Contributor Author

@dkager Would you be able to reviev this?

@lukaszgo1

Copy link
Copy Markdown
Contributor Author

@dkager Ping

@dkager

dkager commented Sep 23, 2018

Copy link
Copy Markdown
Contributor

I thought I had already reviewed the latest version, but apparently not. Will do tomorrow.

@dkager dkager left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good patch, but still a few comments.

class TrayClockWClass(IAccessible):
"""
Based on NVDAObject but the role is changed to clock.
Depending on the version of Windows name or value contains left-to-right or right-to-left characters, so remove them from both.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some double spaces in this comment.

# #4364 On some versions of Windows name contains redundant information that is available either in the role or the value, however on Windows 10 Anniversary Update and later the value is empty, so we cannot simply dismiss the name.
if super(TrayClockWClass, self).value is None:
return super(TrayClockWClass, self).name
return super(TrayClockWClass, self).name.replace(CHAR_LTR_MARK,'').replace(CHAR_RTL_MARK,'')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming at this fresh I think I would put the replacement on its own line, e.g. create a variable holding the name, then a chained replace combined with the return on the next line. I don't know if we recommend a maximum line length though, maybe I'm being fussy.

return None

def _get_value(self):
if super(TrayClockWClass, self).value is None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I would collect the value in its own local variable, perform the replacement only if it is not NOne and finally return the variable.

Comment thread source/appModules/dllhost.py Outdated
# This file may be used under the terms of the GNU General Public License, version 2 or later.
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html

""" Under older builds of Windows 10 (from RTM release to Creators Update) dllhost is used to display a properties window.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double space in comment.

Comment thread source/appModules/dllhost.py Outdated

""" Under older builds of Windows 10 (from RTM release to Creators Update) dllhost is used to display a properties window.
Read-Only edit boxes in it can contain dates that include unwanted left-to-right and right-to-left indicator characters.
This simply imports a proper class from explorer app module, and maps it to a edit control.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"from explorer app module" --> "from the explorer app module"

Comment thread source/appModules/dllhost.py Outdated

def chooseNVDAObjectOverlayClasses(self, obj, clsList):
windowClass = obj.windowClassName

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is so short that I wouldn't put blank line here.

def chooseNVDAObjectOverlayClasses(self, obj, clsList):
windowClass = obj.windowClassName

if windowClass == "Edit":

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But can we be sure that this is read-only? Should you not check the state too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we can, because in explorer.py i am removing RTL and LTR chars only when edit has readonly in states. I've done it this way to avoid additional check in both explorer.py and dllhost.py. The same goes for your last commend.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad for not seeing this. @LeonarddeR what do you think?

Comment thread source/appModules/dllhost.py Outdated

if windowClass == "Edit":
clsList.insert(0, ReadOnlyEditBox)
return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This return statement is redundant because the function ends here anyway.

Comment thread source/appModules/explorer.py Outdated
#These can contain dates that include unwanted left-to-right and right-to-left indicator characters.

def _get_windowText(self):
if super(ReadOnlyEditBox, self).windowText is not None and controlTypes.STATE_READONLY in self.states:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as with the replacements above: this code can be made a bit more readable.

clsList.insert(0, NotificationArea)
return

if windowClass == "Edit":

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we be sure this is read-only?

@lukaszgo1

Copy link
Copy Markdown
Contributor Author

@dkager I believe I've addressed all you commends.

return super(TrayClockWClass, self).name
return None
# #4364 On some versions of Windows name contains redundant information that is available either in the role or the value, however on Windows 10 Anniversary Update and later the value is empty, so we cannot simply dismiss the name.
ClockValue = super(TrayClockWClass, self).value

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would refactor this to:

if super(TrayClockWClass, self).value is None:
	clockName = super(TrayClockWClass, self).name
	return clockName.replace(CHAR_LTR_MARK,'').replace(CHAR_RTL_MARK,'')
return None

Note the lower-case c in clockName.

return ClockName

def _get_value(self):
ClockValue = super(TrayClockWClass, self).value

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the naming conventions for variables, i.e. clockValue.

(None,oleacc.ROLE_SYSTEM_ALERT):"Dialog",
(None,oleacc.ROLE_SYSTEM_PROPERTYPAGE):"Dialog",
(None,oleacc.ROLE_SYSTEM_GROUPING):"Groupbox",
("TrayClockWClass",oleacc.ROLE_SYSTEM_CLIENT):"TrayClockWClass",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this will not break older versions of Windows?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I am. I've tested under Windows 7, 8, 8.1 and all released builds of Windows 10.


def chooseNVDAObjectOverlayClasses(self, obj, clsList):
windowClass = obj.windowClassName
if windowClass == "Edit":

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you addressed the question I had about this line.

@lukaszgo1 lukaszgo1 Sep 29, 2018

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes i do. See {this commend

Comment thread source/appModules/explorer.py Outdated
#These can contain dates that include unwanted left-to-right and right-to-left indicator characters.

def _get_windowText(self):
WindowText = super(ReadOnlyEditBox, self).windowText

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the naming convention for variables, i.e. windowText.

clsList.insert(0, NotificationArea)
return

if windowClass == "Edit":

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you addressed the question I had about this line.

@lukaszgo1

Copy link
Copy Markdown
Contributor Author

@dkager All your commends are now addressed.

@lukaszgo1

Copy link
Copy Markdown
Contributor Author

@LeonarddeR Can you please respod to this @dkager s question?

@lukaszgo1

Copy link
Copy Markdown
Contributor Author

@dkager @LeonarddeR Can one of your please review this and either approve, or request further changes? I'd really like to have it includet in 2019.1, mainly because it fixes a bug which is according to the change log fixed in 2018.2.

@Adriani90

Copy link
Copy Markdown
Collaborator

cc: @michaelDCurran

@dpy013

dpy013 commented Feb 14, 2019

Copy link
Copy Markdown
Contributor

@dkager @LeonarddeR Can one of your please review this and either approve, or request further changes? I'd really like to have it includet in 2019.1, mainly because it fixes a bug which is according to the change log fixed in 2018.2.
I also hope that this PR can appear in the 2019.1 version.


def _get_value(self):
clockValue = super(TrayClockWClass, self).value
if not clockValue is None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the convention is to write
if clockValue is not None:

@lukaszgo1

Copy link
Copy Markdown
Contributor Author

@dkager All done.

@dpy013

dpy013 commented Feb 16, 2019

Copy link
Copy Markdown
Contributor

@dkager All done.
This is good news.

@feerrenrut

Copy link
Copy Markdown
Contributor

I think the main remaining concern is the duplication of the constants for the LTR and RTL mark characters. I would recommend putting these in a module eg (source/unicodeCharConsts.py).

Using git grep "'"'\\u' (in Git bash) shows some other candidates for this:
u'\u3000':'IDEOGRAPHIC SPACE' some of these strings have a space appended.... I haven't inspected the code but I wonder if this a mistake. Alternatively, the goal may be to replace 'IDEOGRAPHIC SPACE' or regular space.
u'\ufffc':OBJECT REPLACEMENT CHARACTER
u'\u0007':BELL

If this turns out to be difficult, then I don't think this should hold up this PR.

@feerrenrut feerrenrut left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your work on this! I'm happy with the changes here.

I noticed in one comment you mentioned you had tested this across different versions of windows? Could you please update the PR description with this information. While it may be obvious to some people, could you also add step by step instructions for testing this to the testing section? It makes it easier for others to understand how you have tested it, perhaps they have other ideas.

I won't merge this immediately, I would like to hear what you think about moving the character constants out to their own module.

@lukaszgo1

Copy link
Copy Markdown
Contributor Author

@feerrenrut I've updated an initial commend with the steps to test this. Is this sufficient? Regarding moving the unicode chars to the separate file it would make source code cleaner, but testing of this might be difficult.
I would rather merge this as is, and then move the unicode symbols in a separate PR ,because these two changes aren't directly related and moving some of these symbols might introduce regressions.

@feerrenrut

Copy link
Copy Markdown
Contributor

Thanks @lukaszgo1, I'll merge this in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

German Win7: LTR and RTL characters still exist in Properties Window (explorer.exe) and in the Taskbar Clock

7 participants