Merge branch 'GP-6899_isabella3412_Help_Accessibility_Page'

This commit is contained in:
Ryan Kurtz
2026-09-18 06:28:21 -04:00
10 changed files with 201 additions and 74 deletions

View File

@@ -250,6 +250,7 @@ src/main/help/help/TOC_Source.xml||GHIDRA||||END|
src/main/help/help/topics/About/About_Ghidra.htm||GHIDRA||||END|
src/main/help/help/topics/About/About_Program_File.htm||GHIDRA||||END|
src/main/help/help/topics/About/images/About_Program.png||GHIDRA||||END|
src/main/help/help/topics/Accessibility/AccessibilityOverview.html||GHIDRA||||END|
src/main/help/help/topics/Annotations/Annotations.html||GHIDRA||||END|
src/main/help/help/topics/Annotations/images/CommentDialogURLExample.png||GHIDRA||||END|
src/main/help/help/topics/Annotations/images/InvalidAnnotationsDialogExample.png||GHIDRA||||END|

View File

@@ -52,7 +52,7 @@
<tocref id="Root">
<tocdef id="Intro" sortgroup="1a" text="Introduction" target="help/topics/Intro/Intro.htm" />
<tocdef id="Getting Started"
sortgroup="a"
text="Getting Started"
@@ -388,6 +388,7 @@
<tocdef id="Glossary" sortgroup="i" text="Glossary" target="help/topics/Glossary/glossary.htm" />
<tocdef id="What's New" sortgroup="j" text="What's New" target="external:docs/WhatsNew.html" />
<tocdef id="Tips of the Day" sortgroup="k" text="Tips of the Day" target="help/topics/Misc/Tips.htm" />
<tocdef id="Accessibility" sortgroup="l" text="Accessibility" target="help/topics/Accessibility/AccessibilityOverview.html" />
<tocdef id="Appendix" sortgroup="z" text="Appendix" target="help/topics/Misc/Appendix.htm">
<tocdef id="Block Models" sortgroup="a" text="Block Models" target="help/topics/BlockModel/Block_Model.htm" />
<tocdef id="Languages" sortgroup="b" text="Languages" target="help/topics/LanguageProviderPlugin/Languages.htm" />

View File

@@ -0,0 +1,115 @@
<!DOCTYPE doctype>
<HTML>
<HEAD>
<META name="generator" content=
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
<TITLE>Accessibility</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
<META name="generator" content="Microsoft FrontPage 4.0">
</HEAD>
<BODY>
<H1 align="center">Ghidra Accessibility</H1>
<BLOCKQUOTE>
<P>Ghidra strives to be as accessible as possible to all users, including those relying on
keyboard-only operation and screen readers. This document summarizes built-in accessibility
features, recommended usage patterns, and known limitations.</P>
<H2>Screen-Reader Guidance</H2>
<BLOCKQUOTE>
<P>Most of Ghidra's UI is built in Java/Swing, so screen reader behavior may differ from a web
browser. To get the best results:</P>
<UL>
<LI>Use a modern Java-aware screen reader (e.g. NVDA on Windows).</LI>
<LI>Enable "focus following caret" or "announce focus changes" so you hear when UI components
gain keyboard focus.</LI>
<LI>Pause briefly after opening new dialogs or views, as Swing can sometimes batch
events.</LI>
</UL>
</BLOCKQUOTE>
<H2>Keyboard Navigation</H2>
<BLOCKQUOTE>
<P>Ghidra provides comprehensive keyboard navigation support to traverse UI components,
windows, and providers. For full details, including focus traversal and navigation shortcuts,
see the <A href="help/topics/KeyboardNavigation/KeyboardNavigation.html">Keyboard
Navigation</A> topic.</P>
</BLOCKQUOTE>
<H2>Quick Action Dialog (Ctrl-3)</H2>
<BLOCKQUOTE>
<P>Ghidra's
<A href="help/topics/KeyboardNavigation/KeyboardNavigation.html#ActionChooserDialog">
Quick Action Dialog</A> provides a fast, keyboard-first way to find and run any action.
Press <B>Ctrl-3</B> to open it, then:</P>
<UL>
<LI>Begin typing any portion of an action name</LI>
<LI>Use <B>Up</B>/<B>Down</B> arrows to navigate the list.</LI>
<LI>Repeat <B>Ctrl + 3</B> to expand from local to global actions.</LI>
<LI>Press <B>Enter</B> to execute the selected command.</LI>
</UL>
<P>The dialog remembers recently used actions across sessions for quick recall. This feature is
invaluable for screen-reader users or anyone who prefers keyboard navigation over menus.</P>
</BLOCKQUOTE>
<H2>Script Launcher (Ctrl-Shift-S)</H2>
<BLOCKQUOTE>
<P>Ghidra's
<A href="help/topics/GhidraScriptMgrPlugin/GhidraScriptMgrPlugin.htm#Script_Quick_Launch">
Script Quick Launcher</A> provides a quick way to run desired scripts.
Press <B>Ctrl-Shift-S</B> to open it, then:
</P>
<UL>
<LI>Begin typing your script's name (wildcards and substrings allowed).</LI>
<LI>Navigate the filtered list with Up/Down, then Enter to run.</LI>
</UL>
<P>The dialog remembers recentlyl used scripts for quick recall.</P>
</BLOCKQUOTE>
<H2>Known Limitations</H2>
<BLOCKQUOTE>
<UL>
<LI>Swing's accessibility support is not as mature as HTML/ARIA. You may encounter missing or
stale descriptions, focus swapping, or limited screen-reader gestures.</LI>
<LI>Browser-style reporting (tabular UI state summaries) is not available.</LI>
</UL>
</BLOCKQUOTE>
</BLOCKQUOTE>
<P class="relatedtopic">Related Topics:</P>
<UL>
<LI><A href="help/topics/KeyboardNavigation/KeyboardNavigation.html">Keyboard
Navigation</A></LI>
<LI><A href="help/topics/GhidraScriptMgrPlugin/GhidraScriptMgrPlugin.htm">Script
Manager</A></LI>
</UL><BR>
</BODY>
</HTML>

View File

@@ -132,7 +132,7 @@
Manager.</P>
</BLOCKQUOTE>
<H3><A name="Script_Quick_Launch"></A>Script Quick Launch</H3>
<H3><A name="Script_Quick_Launch"></A>Script Quick Launcher</H3>
<BLOCKQUOTE>
<P align="left">This key binding action shows a dialog to quickly find and run scripts.

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,17 +20,13 @@ import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;
import docking.ActionContext;
import docking.action.DockingAction;
import docking.action.MenuData;
import docking.tool.ToolConstants;
import ghidra.app.CorePluginPackage;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.framework.main.ApplicationLevelOnlyPlugin;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.framework.preferences.Preferences;
import ghidra.util.HelpLocation;
import ghidra.util.Swing;
import ghidra.util.SystemUtilities;
import utilities.util.FileUtilities;
@@ -48,7 +44,6 @@ public class TipOfTheDayPlugin extends Plugin implements ApplicationLevelOnlyPlu
private static final String SHOW_TIPS = "SHOW_TIPS";
private TipOfTheDayDialog dialog;
private DockingAction action;
public TipOfTheDayPlugin(PluginTool tool) {
super(tool);
@@ -56,19 +51,6 @@ public class TipOfTheDayPlugin extends Plugin implements ApplicationLevelOnlyPlu
@Override
protected void init() {
action = new DockingAction("Tips of the day", getName()) {
@Override
public void actionPerformed(ActionContext context) {
dialog.doShow(tool.getToolFrame());
}
};
action.setMenuBarData(new MenuData(new String[] { "Help", "Tip of the Day" },
ToolConstants.HELP_CONTENTS_MENU_GROUP));
action.setEnabled(true);
action.setHelpLocation(new HelpLocation(ToolConstants.TOOL_HELP_TOPIC, "Tip_of_the_day"));
tool.addAction(action);
List<String> tips = null;
try {
tips = loadTips();
@@ -91,8 +73,6 @@ public class TipOfTheDayPlugin extends Plugin implements ApplicationLevelOnlyPlu
@Override
protected void dispose() {
writePreferences();
action.dispose();
dialog.close();
}
@@ -101,7 +81,7 @@ public class TipOfTheDayPlugin extends Plugin implements ApplicationLevelOnlyPlu
String showTipsStr = Preferences.getProperty(SHOW_TIPS, "true", true);
int tipIndex = Integer.parseInt(tipIndexStr);
final boolean showTips = Boolean.parseBoolean(showTipsStr);
boolean showTips = Boolean.parseBoolean(showTipsStr);
if (showTips) {
tipIndex = (++tipIndex) % dialog.getNumberOfTips();
writePreferences(tipIndex, showTips);
@@ -110,7 +90,7 @@ public class TipOfTheDayPlugin extends Plugin implements ApplicationLevelOnlyPlu
dialog.setTipIndex(tipIndex);
dialog.setShowTips(showTips);
SystemUtilities.runSwingLater(() -> {
Swing.runLater(() -> {
if (showTips && !SystemUtilities.isInTestingMode()) {
dialog.show(tool.getToolFrame());
}

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,6 +16,7 @@
package ghidra.app.plugin.runtimeinfo;
import docking.action.builder.ActionBuilder;
import docking.tool.ToolConstants;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.framework.main.ApplicationLevelOnlyPlugin;
import ghidra.framework.main.UtilityPluginPackage;
@@ -50,7 +51,7 @@ public class RuntimeInfoPlugin extends Plugin implements ApplicationLevelOnlyPlu
.onAction(context -> showInstalledProcessors())
.enabled(true)
.menuPath("Help", supportedActionName)
.menuGroup("YYY") // trying to put this just above the last menu entry
.menuGroup(ToolConstants.HELP_RUNTIME_MENU_GROUP)
.helpLocation(getInstalledProcessorsHelpLocation())
.buildAndInstall(tool);
@@ -59,7 +60,7 @@ public class RuntimeInfoPlugin extends Plugin implements ApplicationLevelOnlyPlu
.onAction(context -> showRuntimeInfo())
.enabled(true)
.menuPath("Help", runtimeInfoActionName)
.menuGroup("YYY")
.menuGroup(ToolConstants.HELP_RUNTIME_MENU_GROUP)
.helpLocation(getRuntimeInfoHelpLocation())
.buildAndInstall(tool);
}

View File

@@ -20,44 +20,57 @@
<BLOCKQUOTE>
<P>Ghidra supports standard keyboard navigation for traversing component focus
cycles within each window. In general, TAB and &lt;CTRL&gt; TAB will transfer focus to
the next component. And &lt;SHIFT&gt; TAB and &lt;CTRL&gt;&lt;SHIFT&gt;TAB will transfer
focus to the previous component in the cycle. TAB and &lt;SHIFT&gt;TAB do not always work
as they are sometimes used by individual components such as text components, but the
&lt;CTRL&gt; versions should work universally.</P>
cycles within each window. In general, <B>Tab</B> and <B>Ctrl-Tab</B> will transfer focus to
the next component. <B>Shift-Tab</B> and <B>Ctrl-Shift-Tab</B> will transfer
focus to the previous component.
<BLOCKQUOTE>
<P><IMG src="help/shared/note.png" border="0">
<B>Tab</B> and <B>Shift-Tab</B> do not always work
as they are sometimes used by individual components, such as text components. The
<B>Ctrl</B> versions should work universally.</P>
</BLOCKQUOTE>
<P>Ghidra also provides some handy shortcut keys for navigation:</P>
<UL>
<LI>&lt;CTRL&gt;F3 - Transfer focus to the next window or dialog.</LI>
<LI><B>Ctrl-F3</B> - Transfer focus (jump) to the next window or dialog.</LI>
<LI>&lt;CTRL&gt;&lt;SHIFT&gt;F3 - Transfer focus to the previous window or dialog.</LI>
<LI><B>Ctrl-Shift-F3</B> - Transfer focus (jump) to the previous window or
dialog.</LI>
<LI>&lt;CTRL&gt;J - Transfer focus (Jump) to the next component provider (titled
<LI><B>Ctrl-J</B> - Transfer focus (jump) to the next component provider (titled
component).</LI>
<LI>&lt;CTRL&gt;&lt;SHIFT&gt;J - Transfer focus (Jump) to the previous component
<LI><B>Ctrl-Shift-J</B> - Transfer focus (jump) to the previous component
provider.</LI>
<LI>
<B>Ctrl-F6</B> - Transfer focus (jump) to the last active component
provider. This allows the user to jump back and forth between recently used provider.
</LI>
</UL>
</BLOCKQUOTE>
<H2>Actions</H2>
<BLOCKQUOTE>
<P>Global menus can be reached using the various accelerator keys such as &lt;ALT&gt;F to
<P>Global menus can be reached using the various accelerator keys such as <B>Alt-F<B> to
access the File menu.</P>
<P>Context menus can be invoked using the &lt;SHIFT&gt;F10 key or the dedicated context
<P>Context menus can be invoked using the Shift-F10 key or the dedicated context
menu key available on some keyboards.</P>
<P>Toolbar actions currently can't be directly accessed via the keyboard unless a
keybinding is assigned to them.</P>
</BLOCKQUOTE>
<H2>Actions Dialog</H2><A NAME="ActionChooserDialog"/>
<A NAME="ActionChooserDialog"/><H2>Quick Action Dialog</H2>
<BLOCKQUOTE>
<P>The Actions Dialog displays a list of all actions (or commands) relevant to the
<P>The Quick Action Dialog displays a list of all actions (or commands) relevant to the
currently focused component window or dialog and allows the user to select and invoke any
valid, enabled action using either the mouse or keyboard.</P>
@@ -70,24 +83,24 @@
<P>Initially, the dialog shows just the local toolbar and menu items for the currently
focused component, along with all relevant popup and keyboard actions. Repeatedly
pressing the keybinding assigned to this action (default is &LT;CTRL&GT; 3) will show
pressing the keybinding assigned to this action (default is <B>Ctrl-3</B>) will show
additional, less relevant actions.
<P>Displayed actions in the list can be selected via the mouse or by using the up/down
arrows to move the current selection. Pressing the OK button or pressing the
&lt;ENTER&gt; key will cause the dialog to close and the action to be invoked.</P>
<B>Enter</B> key will cause the dialog to close and the action to be invoked.</P>
<P>Also, the list can be filtered by typing in the provided text box.</P>
<BLOCKQUOTE>
<P><IMG border="0" src="help/shared/note.png" alt="">This dialog can be invoked using
its assigned keybinding (default is &LT;CTRL&GT; 3).</P>
its assigned keybinding (default is <B>Ctrl-3</B>).</P>
<P><IMG border="0" src="help/shared/note.png" alt="">Help (F1) and Assign Keybinding
(F4) actions work on the selected action.</P>
<P><IMG border="0" src="help/shared/note.png" alt="">Help (<B>F1</B>) and Assign Keybinding
(<B>F4</B>) actions work on the selected action.</P>
<P><IMG border="0" src="help/shared/note.png" alt="">Bringing up this dialog and pressing
(&lt;CTRL&gt; 3) a few times to show all local and global actions is a great way to
(<B>Ctrl-3</B>) a few times to show all local and global actions is a great way to
explore all the actions Ghidra actions. </P>

View File

@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -81,6 +81,9 @@ public interface ToolConstants extends DockingToolConstants {
/** A group for actions that link directly to help content */
public static final String HELP_CONTENTS_MENU_GROUP = "AAAHelpContents";
/** A group for actions that show system runtime information */
public static final String HELP_RUNTIME_MENU_GROUP = "RRRHelpContents";
/**
* Constant for the options menu group for the Tool Options menu item
*/

View File

@@ -788,14 +788,15 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
addHelpActions();
// our log file action
DockingAction action = new DockingAction("Show Log", ToolConstants.TOOL_OWNER) {
DockingAction action = new DockingAction("View Log", ToolConstants.TOOL_OWNER) {
@Override
public void actionPerformed(ActionContext context) {
showGhidraUserLogFile();
}
};
action.setMenuBarData(
new MenuData(new String[] { ToolConstants.MENU_HELP, "Show Log" }, null, "BBB"));
new MenuData(new String[] { ToolConstants.MENU_HELP, "Show Log" }, null,
ToolConstants.HELP_RUNTIME_MENU_GROUP));
action.setEnabled(true);
addAction(action);

View File

@@ -1123,6 +1123,37 @@ public abstract class PluginTool extends AbstractDockingTool {
}
protected void addHelpActions() {
HelpService help = Help.getHelpService();
int subgroup = 0;
new ActionBuilder("Contents", ToolConstants.TOOL_OWNER)
.menuPath(ToolConstants.MENU_HELP, "&Contents")
.menuGroup(ToolConstants.HELP_CONTENTS_MENU_GROUP, Integer.toString(subgroup++))
.helpLocation(new HelpLocation("Misc", "Welcome_to_Ghidra_Help"))
.inWindow(ActionBuilder.When.ALWAYS)
.onAction(c -> help.showHelp(null, false, getToolFrame()))
.buildAndInstall(this);
new ActionBuilder("Accessibility", ToolConstants.TOOL_OWNER)
.menuPath(ToolConstants.MENU_HELP, "&Accessibility")
.menuGroup(ToolConstants.HELP_CONTENTS_MENU_GROUP, Integer.toString(subgroup++))
.helpLocation(new HelpLocation("Accessibility", "AccessibilityOverview"))
.inWindow(ActionBuilder.When.ALWAYS)
.onAction(c -> {
help.showHelp(new HelpLocation("Accessibility", "AccessibilityOverview"));
})
.buildAndInstall(this);
new ActionBuilder("User Agreement", ToolConstants.TOOL_OWNER)
.menuPath(ToolConstants.MENU_HELP, "&User Agreement")
.menuGroup(ToolConstants.HELP_CONTENTS_MENU_GROUP, Integer.toString(subgroup++))
.helpLocation(new HelpLocation(ToolConstants.ABOUT_HELP_TOPIC, "User_Agreement"))
.inWindow(ActionBuilder.When.ALWAYS)
.onAction(
c -> DockingWindowManager.showDialog(new UserAgreementDialog(false, false)))
.buildAndInstall(this);
new ActionBuilder("About Ghidra", ToolConstants.TOOL_OWNER)
.menuPath(ToolConstants.MENU_HELP, "&About Ghidra")
.menuGroup("ZZA")
@@ -1131,16 +1162,7 @@ public abstract class PluginTool extends AbstractDockingTool {
.onAction(c -> DockingWindowManager.showDialog(new AboutDialog()))
.buildAndInstall(this);
new ActionBuilder("User Agreement", ToolConstants.TOOL_OWNER)
.menuPath(ToolConstants.MENU_HELP, "&User Agreement")
.menuGroup(ToolConstants.HELP_CONTENTS_MENU_GROUP)
.helpLocation(new HelpLocation(ToolConstants.ABOUT_HELP_TOPIC, "User_Agreement"))
.inWindow(ActionBuilder.When.ALWAYS)
.onAction(
c -> DockingWindowManager.showDialog(new UserAgreementDialog(false, false)))
.buildAndInstall(this);
final ErrorReporter reporter = ErrLogDialog.getErrorReporter();
ErrorReporter reporter = ErrLogDialog.getErrorReporter();
if (reporter != null) {
new ActionBuilder("Report Bug", ToolConstants.TOOL_OWNER)
.menuPath(ToolConstants.MENU_HELP, "&Report Bug...")
@@ -1150,16 +1172,6 @@ public abstract class PluginTool extends AbstractDockingTool {
.onAction(c -> reporter.report(getToolFrame(), "User Bug Report", null))
.buildAndInstall(this);
}
HelpService help = Help.getHelpService();
new ActionBuilder("Contents", ToolConstants.TOOL_OWNER)
.menuPath(ToolConstants.MENU_HELP, "&Contents")
.menuGroup(ToolConstants.HELP_CONTENTS_MENU_GROUP)
.helpLocation(new HelpLocation("Misc", "Welcome_to_Ghidra_Help"))
.inWindow(ActionBuilder.When.ALWAYS)
.onAction(c -> help.showHelp(null, false, getToolFrame()))
.buildAndInstall(this);
}
/**