Skip to content

Commit

Permalink
Make the SearchBox announce if it found results or not (#12301)
Browse files Browse the repository at this point in the history
Basically, this is the same as #12266, but for the `SearchBoxControl`. Trickily, the ControlCore is the one that knows if there were search results, but the TermControl has to be the one to announce it.

* [x] Will take care of #11973 once a11y team confirms
* [x] Tested manually with Narrator
* [x] Resolves a part of #6319, which I'm repurposing just to displaying the number of results in general.
* See also #3920

(cherry picked from commit fbe0416)
  • Loading branch information
zadjii-msft authored and DHowett committed Feb 1, 2022
1 parent 5664cf8 commit e103a73
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1285,12 +1285,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation

::Search search(*GetUiaData(), text.c_str(), direction, sensitivity);
auto lock = _terminal->LockForWriting();
if (search.FindNext())
const bool foundMatch{ search.FindNext() };
if (foundMatch)
{
_terminal->SetBlockSelection(false);
search.Select();
_renderer->TriggerSelection();
}

// Raise a FoundMatch event, which the control will use to notify
// narrator if there was any results in the buffer
auto foundResults = winrt::make_self<implementation::FoundResultsArgs>(foundMatch);
_FoundMatchHandlers(*this, *foundResults);
}

void ControlCore::SetBackgroundOpacity(const double opacity)
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
TYPED_EVENT(RaiseNotice, IInspectable, Control::NoticeEventArgs);
TYPED_EVENT(TransparencyChanged, IInspectable, Control::TransparencyChangedEventArgs);
TYPED_EVENT(ReceivedOutput, IInspectable, IInspectable);
TYPED_EVENT(FoundMatch, IInspectable, Control::FoundResultsArgs);
// clang-format on

private:
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/ControlCore.idl
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ namespace Microsoft.Terminal.Control
event Windows.Foundation.TypedEventHandler<Object, NoticeEventArgs> RaiseNotice;
event Windows.Foundation.TypedEventHandler<Object, TransparencyChangedEventArgs> TransparencyChanged;
event Windows.Foundation.TypedEventHandler<Object, Object> ReceivedOutput;
event Windows.Foundation.TypedEventHandler<Object, FoundResultsArgs> FoundMatch;

};
}
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/EventArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
#include "ScrollPositionChangedArgs.g.cpp"
#include "RendererWarningArgs.g.cpp"
#include "TransparencyChangedEventArgs.g.cpp"
#include "FoundResultsArgs.g.cpp"
12 changes: 12 additions & 0 deletions src/cascadia/TerminalControl/EventArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "ScrollPositionChangedArgs.g.h"
#include "RendererWarningArgs.g.h"
#include "TransparencyChangedEventArgs.g.h"
#include "FoundResultsArgs.g.h"
#include "cppwinrt_utils.h"

namespace winrt::Microsoft::Terminal::Control::implementation
Expand Down Expand Up @@ -131,4 +132,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation

WINRT_PROPERTY(double, Opacity);
};

struct FoundResultsArgs : public FoundResultsArgsT<FoundResultsArgs>
{
public:
FoundResultsArgs(const bool foundMatch) :
_FoundMatch(foundMatch)
{
}

WINRT_PROPERTY(bool, FoundMatch);
};
}
6 changes: 6 additions & 0 deletions src/cascadia/TerminalControl/EventArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,10 @@ namespace Microsoft.Terminal.Control
{
Double Opacity { get; };
}


runtimeclass FoundResultsArgs
{
Boolean FoundMatch { get; };
}
}
8 changes: 8 additions & 0 deletions src/cascadia/TerminalControl/Resources/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,12 @@ Please either install the missing font or choose another one.</value>
<data name="TermControlReadOnly" xml:space="preserve">
<value>Read-only mode is enabled.</value>
</data>
<data name="SearchBox_MatchesAvailable" xml:space="preserve">
<value>Results found</value>
<comment>Announced to a screen reader when the user searches for some text and there are matches for that text in the terminal.</comment>
</data>
<data name="SearchBox_NoMatches" xml:space="preserve">
<value>No results found</value>
<comment>Announced to a screen reader when the user searches for some text and there are no matches for that text in the terminal.</comment>
</data>
</root>
25 changes: 25 additions & 0 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_core.TransparencyChanged({ this, &TermControl::_coreTransparencyChanged });
_core.RaiseNotice({ this, &TermControl::_coreRaisedNotice });
_core.HoveredHyperlinkChanged({ this, &TermControl::_hoveredHyperlinkChanged });
_core.FoundMatch({ this, &TermControl::_coreFoundMatch });
_interactivity.OpenHyperlink({ this, &TermControl::_HyperlinkHandler });
_interactivity.ScrollPositionChanged({ this, &TermControl::_ScrollPositionChanged });

Expand Down Expand Up @@ -2601,4 +2602,28 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
return _core.ReadEntireBuffer();
}

// Method Description:
// - Called when the core raises a FoundMatch event. That's done in response
// to us starting a search query with ControlCore::Search.
// - The args will tell us if there were or were not any results for that
// particular search. We'll use that to control what to announce to
// Narrator. When we have more elaborate search information to report, we
// may want to report that here. (see GH #3920)
// Arguments:
// - args: contains information about the results that were or were not found.
// Return Value:
// - <none>
void TermControl::_coreFoundMatch(const IInspectable& /*sender*/, const Control::FoundResultsArgs& args)
{
if (auto automationPeer{ Automation::Peers::FrameworkElementAutomationPeer::FromElement(*this) })
{
automationPeer.RaiseNotificationEvent(
Automation::Peers::AutomationNotificationKind::ActionCompleted,
Automation::Peers::AutomationNotificationProcessing::ImportantMostRecent,
args.FoundMatch() ? RS_(L"SearchBox_MatchesAvailable") : RS_(L"SearchBox_NoMatches"), // what to announce if results were found
L"SearchBoxResultAnnouncement" /* unique name for this group of notifications */);
}
}

}
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
winrt::fire_and_forget _coreTransparencyChanged(IInspectable sender, Control::TransparencyChangedEventArgs args);
void _coreRaisedNotice(const IInspectable& s, const Control::NoticeEventArgs& args);
void _coreWarningBell(const IInspectable& sender, const IInspectable& args);
void _coreFoundMatch(const IInspectable& sender, const Control::FoundResultsArgs& args);
};
}

Expand Down

1 comment on commit e103a73

@github-actions
Copy link

@github-actions github-actions bot commented on e103a73 Feb 1, 2022

Choose a reason for hiding this comment

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

@check-spelling-bot Report

Unrecognized words, please review:

  • hwinsta
  • Lsa
  • lsass
  • UOI
  • USEROBJECTFLAGS
  • winsta
  • winstamin
  • WSF
Previously acknowledged words that are now absent adaa carlos coffgroup coffgrp datetime deconstructed devicefamily dpg eae emplate GENPROFILE GTR guardxfg HHmm Hostx installationpath MMdd pgorepro pgort PGU sid SPACEBAR timelines Unregister vcvarsall xfg xIcon yIcon zamora
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the git@github.com:microsoft/terminal.git repository
on the release-1.12 branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect/alphabet.txt
.github/actions/spelling/expect/expect.txt
.github/actions/spelling/expect/web.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect/e103a7364b61906a96253d806f15a3105c30f2dc.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/microsoft/terminal/comments/65753565" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
✏️ Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

⚠️ The command is written for posix shells. You can copy the contents of each perl command excluding the outer ' marks and dropping any '"/"' quotation mark pairs into a file and then run perl file.pl from the root of the repository to run the code. Alternatively, you can manually insert the items...

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉

🗜️ If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to a patterns/{file}.txt.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

Please sign in to comment.