dictation-toolbox / Caster

Dragonfly-Based Voice Programming and Accessibility Toolkit
https://dictation-toolbox.github.io/Caster/
Other
340 stars 121 forks source link

Implemented Window Switch Manager #881

Open LexiconCode opened 3 years ago

LexiconCode commented 3 years ago

Description

Window Switch Manager to swap windows by saying words in their title. In addition a command to restore the last minimized window.

Commands:

"window switch <windows>" -> switch to the window with the given word in its
                             title. If multiple windows have that word in
                             their title, then you can say more words in the
                             window's title to disambiguate which one you
                             mean. If you don't, the caster messaging window will be
                             foregrounded instead with info on which windows
                             are ambiguously being matched by your keywords.
"window switch refresh" -> manually reload the list of windows. Useful while
                     developing if you don't want to use the timer. Command disabled
"window switch show" -> output information about which keywords can
                            be used on their own to switch windows and which
                            require multiple words.

"""

Commands have been renamed minimize win window minimize following the object verb model.

Related Issue

https://github.com/dictation-toolbox/Caster/issues/797

Motivation and Context

Motivation is to make it easy for users to switch windows by voice.

How Has This Been Tested

This is been tested on Windows 10 but should be cross-platform. The list of Windows is rebuilt every 2 seconds using a dragonfly timer updating open_windows_dictlist This allows for weighted commands rather than parsing free dictation. Testing on other systems would be beneficial as seeing if there's any impact on performance.

Types of changes

Checklist

Maintainer/Reviewer Checklist

LexiconCode commented 3 years ago

Some work needs to be done to print out correctly unmatched commands for window titles.

Done - Waiting for any feedback before merge.

kendonB commented 2 years ago

I get this one every two seconds (likely due to the refresh):

Traceback (most recent call last):
  File "/home/kendonb/.local/lib/python3.8/site-packages/dragonfly/engines/base/timer.py", line 91, in call
    self.function()
  File "/home/kendonb/caster/castervoice/rules/core/navigation_rules/window_mgmt_rule_support.py", line 47, in refresh_open_windows_dictlist
    for window in (x for x in Window.get_all_windows() if
  File "/home/kendonb/caster/castervoice/rules/core/navigation_rules/window_mgmt_rule_support.py", line 48, in <genexpr>
    x.is_valid and
AttributeError: 'X11Window' object has no attribute 'is_valid'
LexiconCode commented 2 years ago

Thanks for testing this on Linux.

is_valid is Win32Window property for Windows only. It appears every two seconds because it refreshes grabbing all the windows and checks Windows to make sure they're valid.

The code should be able to be adjusted to check for OS in this case.

drmfinlay commented 4 months ago

@LexiconCode I think I must have missed this PR. It looks quite useful, even for Dragon users.

Obviously you haven't worked on it in a while, but I would like to suggest updating the <windows> list in the grammar's process_begin() method instead of with an engine timer. Lists like this only need to be updated when the user starts speaking. Also avoids the above problem with Win32Window.is_valid.

LexiconCode commented 4 months ago

That's some great feedback, I really didn't like using an engine timer wasting cycles.

drmfinlay commented 4 months ago

Thanks! I'm not sure which grammar the rule is part of though.

Also, the is_valid property is not needed here, since get_all_windows() only returns valid windows. is_visible is probably sufficient.