GP-1049 - Fixed a modal parenting issue with the Tip of the Day plugin.

This commit is contained in:
dragonmacher 2021-06-17 17:13:24 -04:00
parent 82c8ba1a1c
commit 23958bb12f
2 changed files with 36 additions and 30 deletions

View file

@ -44,21 +44,21 @@ import ghidra.util.task.TaskMonitorAdapter;
* Main Ghidra application class. Creates * Main Ghidra application class. Creates
* the .ghidra folder that contains the user preferences and tools if it does * the .ghidra folder that contains the user preferences and tools if it does
* not exist. Initializes JavaHelp and attempts to restore the last opened * not exist. Initializes JavaHelp and attempts to restore the last opened
* project. * project.
* <p> A list of classes for plugins, data types, and language providers is * <p> A list of classes for plugins, data types, and language providers is
* maintained so that a search of the classpath is not done every time * maintained so that a search of the classpath is not done every time
* Ghidra is run. The list is maintained in the GhidraClasses.xml file * Ghidra is run. The list is maintained in the GhidraClasses.xml file
* in the user's .ghidra folder. A search of the classpath is done if the * in the user's .ghidra folder. A search of the classpath is done if the
* (1) GhidraClasses.xml file is not found, (2) the classpath is different * (1) GhidraClasses.xml file is not found, (2) the classpath is different
* from when the last time Ghidra was run, (3) a class in the file was * from when the last time Ghidra was run, (3) a class in the file was
* not found, or (4) a modification date specified in the classes file for * not found, or (4) a modification date specified in the classes file for
* a jar file is older than the actual jar file's modification date. * a jar file is older than the actual jar file's modification date.
* *
* <p><strong>Note</strong>: The Plugin path is a user preference that * <p><strong>Note</strong>: The Plugin path is a user preference that
* indicates locations for where classes for plugins and data types should * indicates locations for where classes for plugins and data types should
* be searched; the Plugin path can include jar files just like a classpath. * be searched; the Plugin path can include jar files just like a classpath.
* The Plugin path can be changed by using the <i>Edit Plugin Path</i> dialog, * The Plugin path can be changed by using the <i>Edit Plugin Path</i> dialog,
* displayed from the <i>Edit-&gt;Edit Plugin Path...</i> menu option on the main * displayed from the <i>Edit-&gt;Edit Plugin Path...</i> menu option on the main
* Ghidra project window. * Ghidra project window.
* *
* @see ghidra.GhidraLauncher * @see ghidra.GhidraLauncher
@ -105,7 +105,7 @@ public class GhidraRun implements GhidraLaunchable {
} }
private String processArguments(String[] args) { private String processArguments(String[] args) {
//TODO remove this special handling when possible //TODO remove this special handling when possible
if (args.length == 1 && (args[0].startsWith("-D") || args[0].indexOf(" -D") >= 0)) { if (args.length == 1 && (args[0].startsWith("-D") || args[0].indexOf(" -D") >= 0)) {
args = args[0].split(" "); args = args[0].split(" ");
} }
@ -143,6 +143,16 @@ public class GhidraRun implements GhidraLaunchable {
updateSplashScreenStatusMessage("Creating project manager..."); updateSplashScreenStatusMessage("Creating project manager...");
ProjectManager pm = new GhidraProjectManager(); ProjectManager pm = new GhidraProjectManager();
updateSplashScreenStatusMessage("Creating front end tool..."); updateSplashScreenStatusMessage("Creating front end tool...");
// Show this warning before creating the tool. If we create the tool first, then we may
// see odd dialog behavior caused tool plugins creating dialogs during initialization.
if (Application.isTestBuild()) {
Msg.showWarn(GhidraRun.class, null, "Unsupported Ghidra Distribution",
"WARNING! Please be aware that this is an unsupported and uncertified\n" +
"build of Ghidra! This software may be unstable and data created\n" +
"may be incompatible with future releases.");
}
FrontEndTool tool = new FrontEndTool(pm); FrontEndTool tool = new FrontEndTool(pm);
boolean reopen = true; boolean reopen = true;
@ -164,13 +174,6 @@ public class GhidraRun implements GhidraLaunchable {
projectLocator = pm.getLastOpenedProject(); projectLocator = pm.getLastOpenedProject();
} }
if (Application.isTestBuild()) {
Msg.showWarn(GhidraRun.class, tool.getToolFrame(), "Unsupported Ghidra Distribution",
"WARNING! Please be aware that this is an unsupported and uncertified\n" +
"build of Ghidra! This software may be unstable and data created\n" +
"may be incompatible with future releases.");
}
tool.setVisible(true); tool.setVisible(true);
if (projectLocator != null) { if (projectLocator != null) {

View file

@ -1384,7 +1384,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
focusedPlaceholder.setSelected(false); focusedPlaceholder.setSelected(false);
} }
// Activating placeholders is done to help users find widgets hiding in plain sight. // Activating placeholders is done to help users find widgets hiding in plain sight.
// Assume that the user is no longer seeking a provider if they are clicking around. // Assume that the user is no longer seeking a provider if they are clicking around.
activatedInfo.clear(); activatedInfo.clear();
@ -1708,8 +1708,8 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
* positioning. * positioning.
* *
* <p>Warning: this method allows user to explicitly pass a parent window and component over * <p>Warning: this method allows user to explicitly pass a parent window and component over
* which to be centered. There is no reason to use this method in the standard workflow. * which to be centered. There is no reason to use this method in the standard workflow.
* This method exists strictly to handle future unforeseen use cases. Use at your own * This method exists strictly to handle future unforeseen use cases. Use at your own
* risk of incorrectly parenting dialogs. * risk of incorrectly parenting dialogs.
* *
* @param parent the component whose window over which the given dialog will be shown; cannot * @param parent the component whose window over which the given dialog will be shown; cannot
@ -1740,7 +1740,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
// //
// Note: prefer the active window; allow user's choice of center component when it is // Note: prefer the active window; allow user's choice of center component when it is
// in the active window // in the active window
// //
if (centeredOnComponent != null && if (centeredOnComponent != null &&
SwingUtilities.isDescendingFrom(centeredOnComponent, bestParent)) { SwingUtilities.isDescendingFrom(centeredOnComponent, bestParent)) {
bestCenter = centeredOnComponent; bestCenter = centeredOnComponent;
@ -1764,9 +1764,12 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
bestParent = getBestNonModalParent(provider, bestParent); bestParent = getBestNonModalParent(provider, bestParent);
} }
if (bestParent == null) { // We should no longer need this code. If the above could not find a suitable parent, then
bestParent = getJavaActiveWindow(); // we can allow a null return value, which should signal to Java to pick a reasonable parent.
} // If we put this code back, then make sure the chosen window is not transient.
// if (bestParent == null) {
// bestParent = getActiveNonTransientWindow();
// }
if (bestParent != null && !bestParent.isShowing()) { if (bestParent != null && !bestParent.isShowing()) {
bestParent = null; // don't let non-showing windows be parents bestParent = null; // don't let non-showing windows be parents
@ -1803,7 +1806,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
int activeId = activeProvider.getId(); int activeId = activeProvider.getId();
int providerId = providerToShow.getId(); int providerId = providerToShow.getId();
if (providerId < activeId) { if (providerId < activeId) {
// The provider being shown is older than the active window--do not parent the provider // The provider being shown is older than the active window--do not parent the provider
// to that window. The older age suggests that the new provider was shown on a delay // to that window. The older age suggests that the new provider was shown on a delay
// and should really be considered to live behind the active modal dialog. // and should really be considered to live behind the active modal dialog.
return bestParent; return bestParent;
@ -1811,14 +1814,14 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
if (activeProvider.isTransient()) { if (activeProvider.isTransient()) {
// This prevents transient modal dialogs from being parents to non-modal dialogs. This // This prevents transient modal dialogs from being parents to non-modal dialogs. This
// can cause the non-modal dialog to be closed when the transient modal dialog goes // can cause the non-modal dialog to be closed when the transient modal dialog goes
// away. There is the possibility of the non-modal dialog being blocked if not parented // away. There is the possibility of the non-modal dialog being blocked if not parented
// the this modal dialog. If we find a use case that exposes this pattern, then we // the this modal dialog. If we find a use case that exposes this pattern, then we
// will have to revisit how this method chooses to parent. // will have to revisit how this method chooses to parent.
return bestParent; return bestParent;
} }
// //
// The active window is modal. We must make it the non-modal dialog's parent to // The active window is modal. We must make it the non-modal dialog's parent to
// prevent blocking the non-modal. // prevent blocking the non-modal.
// //
@ -2194,7 +2197,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
* Shows a popup menu over the given component. If this given component is not part of the * Shows a popup menu over the given component. If this given component is not part of the
* docking windows hierarchy, then no action is taken. * docking windows hierarchy, then no action is taken.
* *
* @param component the component * @param component the component
*/ */
public static void showContextMenu(Component component) { public static void showContextMenu(Component component) {