Closed Wall-AF closed 1 year ago
Works fine with Linux and Java 11.
I had another user here try it with a Windows 10 variant (Windows Server 2016) with Java 11 and he does not see the problem you describe. @Wall-AF Is it possible for you to try using Java 11 and see if you can reproduce the problem.
Re-opened pending your feedback. Developer was thinking of when you first requested support for the Shift-F10 (right mouse-click) support (#2811)
I have just tried it using Java 11.0.2 with the same result (i.e. no focus and must use mouse (or mousekeys) to get focus, using Alt+Tab
doesn't refocus either). FYI, I'm running Ghidra from within eclipse.
When in this state, press the secret focus reporting key binding combination: Ctrl-Alt-Shift-F2
This will dump a summary of focus info.
When in this state, press the secret focus reporting key binding combination:
Ctrl-Alt-Shift-F2
This will dump a summary of focus info.
Mmm. No success here. Can't see any dump anywhere!
Hmm... It should go to the console / log file. However, there may be a chicken / egg problem here. It's possible that Java is not detecting your keyboard input at all, rendering that command useless.
I use StickyKeys to place a hold on the modifier keys (Alt, Ctrl, Shift & Win).
@dragonmacher @ghidra1 any progress???
I still cannot reproduce the issue. This makes my normal troubleshooting ineffective. I have some things I could try to debug the issue, but not way of knowing the effect.
Do you run from a distribution of Ghidra, or from a pull of the repo master branch? If running from our repo, then you have the ability to try code changes. If that is the case, then I can offer code snippets for testing.
I'm running it from inside Eclipse.
Ok. Are you able to change Ghidra source code, such as the ghidra.app.plugin.core.decompile.actions.FillOutStructureCmd
and then run with those changes?
I can, but which changes?
I can, but which changes?
Inside of FillOutStructureCmd
, change this:
public CreateInternalStructureAction(StructureEditorProvider provider) {
super(provider, EDIT_ACTION_PREFIX + ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
setDescription(DESCRIPTION);
adjustEnablement();
}
@Override
public void actionPerformed(ActionContext context) {
int[] selectedComponentRows = model.getSelectedComponentRows();
boolean hasComponentSelection = model.hasComponentSelection();
to this:
public CreateInternalStructureAction(StructureEditorProvider provider) {
super(provider, EDIT_ACTION_PREFIX + ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON);
setDescription(DESCRIPTION);
adjustEnablement();
}
@Override
public void actionPerformed(ActionContext context) {
Swing.runLater(this::doActionPerformed);
}
public void doActionPerformed() {
int[] selectedComponentRows = model.getSelectedComponentRows();
boolean hasComponentSelection = model.hasComponentSelection();
Basically, this just adds one new method to delegate to the original code 'later'.
Inside of
FillOutStructureCmd
, change this:public CreateInternalStructureAction(StructureEditorProvider provider) { super(provider, EDIT_ACTION_PREFIX + ACTION_NAME, GROUP_NAME, POPUP_PATH, null, ICON); setDescription(DESCRIPTION); adjustEnablement(); } @Override public void actionPerformed(ActionContext context) { int[] selectedComponentRows = model.getSelectedComponentRows(); boolean hasComponentSelection = model.hasComponentSelection();
only exists in CreateInternalStructureAction.java
, and I changed it there, but it made no difference.
To reproduce (on a Windows box):
Structure Editor
Shift+F10
equivalent key to bring up the context menuCreate Structure From Selection
option<Enter>
to choose the option (do not use the mouse)only exists in CreateInternalStructureAction.java, and I changed it there, but it made no difference.
Yes, I'm sorry, I had the wrong class name
Ok. You can undo that change. Something else to try. Inside of DockingDialog
, change this:
private Runnable requestFocusRunnable = () -> {
if (focusComponent != null) {
focusComponent.requestFocus();
hasBeenFocused = true;
}
};
to this:
private Runnable requestFocusRunnable = () -> {
Msg.debug(this, "calling request focus on: " + focusComponent);
if (focusComponent != null) {
focusComponent.requestFocusInWindow();
hasBeenFocused = true;
}
};
Note the added print statement and the change to requestFocusInWindow();
(This likely will not fix the issue, but it may help provide more info.)
Mmm, interesting! The debug message does not appear when just using the <Enter>
key (step 5 above), but does if using the mouse, suggesting that method private Runnable requestFocusRunnable
isn't even being called.
Upon further investigation, when using the mouse, the windowActivated
override gets called twice whereas using the keyboard it only gets called once! Only on the second occasion does component.getFocusComponent()
return a non-null response.
With this version:
@Override
public void windowActivated(WindowEvent e) {
ghidra.util.Msg.debug(this, "calling windowActivated on: " + focusComponent
+ " : hasBeenFocused=" + hasBeenFocused);
if (!hasBeenFocused) {
Component newFocusComponent = component.getFocusComponent();
ghidra.util.Msg.debug(this, "calling windowActivated, component= " + newFocusComponent);
if (newFocusComponent != null) {
focusComponent = newFocusComponent;
SwingUtilities.invokeLater(requestFocusRunnable);
}
}
}
Output when using <Enter>
key:
DEBUG calling windowActivated on: docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@622ac4cc,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING] : hasBeenFocused=false (DockingDialog.java:204)
DEBUG calling windowActivated, component= null (DockingDialog.java:208)
Output when using the mouse:
DEBUG calling windowActivated on: docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@622ac4cc,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING] : hasBeenFocused=false (DockingDialog.java:204)
DEBUG calling windowActivated, component= null (DockingDialog.java:208)
DEBUG calling windowActivated on: docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@622ac4cc,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING] : hasBeenFocused=false (DockingDialog.java:204)
DEBUG calling windowActivated, component= docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@622ac4cc,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING] (DockingDialog.java:208)
DEBUG calling request focus on: docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@622ac4cc,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING] (DockingDialog.java:48)
Now let's see what Java thinks the focus state of the system is after everything has settled down.
Update the requestFocusRunnable
to look like this:
private Runnable requestFocusRunnable = () -> {
Msg.debug(this, "\tcalling request focus on: " + focusComponent);
if (focusComponent != null) {
boolean didFocus = focusComponent.requestFocusInWindow();
Msg.debug(this, "\tdid focus?: " + didFocus);
GTimer.scheduleRunnable(2000, () -> {
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
Window window = kfm.getActiveWindow();
Window focusedWindow = kfm.getFocusedWindow();
Component focusOwner = kfm.getFocusOwner();
Msg.debug(this, "active window: " + window + "\n\tfocused window: " +
focusedWindow + "\n\tfocus owner: " + focusOwner);
});
hasBeenFocused = true;
}
};
This is using a 2 second timer to show the focus info.
That makes no difference because the SwingUtilities.invokeLater(requestFocusRunnable);
isn't called from:
https://github.com/NationalSecurityAgency/ghidra/blob/e5a8f26347e480292580f252806bda9a4e49b814/Ghidra/Framework/Docking/src/main/java/docking/DockingDialog.java#L200-L212
As I tried to explain https://github.com/NationalSecurityAgency/ghidra/issues/4066#issuecomment-1401730084.
The use of the timer was to allow any buffered events to settle down. (Sometimes system events cause more events to be buffered and execute at a later time, which an invokeLater()
would not handle.
Also, the timer's use was not to fix your issue, but to provide diagnostics relating to what Java considers the focused element.
I understood that, but that timer doesn't even get started.
I see. I missed that earlier. In that case, I am curious to know the value of component
when the null
value is returned (thus preventing the notification). This would look something like this:
@Override
public void windowActivated(WindowEvent e) {
ghidra.util.Msg.debug(this, "calling windowActivated on: " + focusComponent
+ " : hasBeenFocused=" + hasBeenFocused);
if (!hasBeenFocused) {
Component newFocusComponent = component.getFocusComponent();
ghidra.util.Msg.debug(this, "calling windowActivated, component= " + component + "; focused comp="+newFocusComponent);
if (newFocusComponent != null) {
focusComponent = newFocusComponent;
SwingUtilities.invokeLater(requestFocusRunnable);
}
}
}
DEBUG calling windowActivated on: null : hasBeenFocused=false (DockingDialog.java:228)
DEBUG calling windowActivated, component= Editor: Create Structure From Selection; focused comp=null (DockingDialog.java:232)
The issue appears to be that Java is not correctly generating a window activated event for the new "Specify the Structure's Name" dialog. On my system, I am seeing the correct event, as you do when using the mouse.
It appears as though you have not tried Java 17. It is unlikely that will fix the issue, but something worth trying.
There is a more invasive way to track the exchange / handshake for window activated and focused events. That would require debug information in a different class, with much more output to interpret. Let me know if you are still interested in debugging this further.
I'm using:
Windows 11 Pro (64-bit) version 10.0.22621.819
D:\GIT_Sources\Ghidra\ghidra>java -version
java version "17.0.3.1" 2022-04-22 LTS
Java(TM) SE Runtime Environment (build 17.0.3.1+2-LTS-6)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.3.1+2-LTS-6, mixed mode, sharing)
If you'd like to keep debugging, the next step I would take is to see the series of events given to us by Java. Firstly, are they different in your 2 use cases? Secondly, if they are the same from Java, is Ghidra doing something to drop the problem case?
To debug this, I use DockingWindowManager.propertyChange()
. This is the method we use to get notified of all focus changes. We attempt to keep our system in sync with Java in this method. It is quite complicated. But, you can print the events received and the windows and components involved. This will allow you to see the actors involved in both use cases.
Where and how? Are you sure you can't replicate???
We have tried on multiple OSes virtual and native. It works consistently for us.
The debugging I suggested would just be more print statements, similar to what we have already done. The location is the docking.DockingWindowManager
in the method propertyChange()
. I understand that this is quite annoying. There is nothing else I can think of to troubleshoot this on our end.
Also, clearly there's a difference as shown in the output of https://github.com/NationalSecurityAgency/ghidra/issues/4066#issuecomment-1401730084 where the windowActivated
is called once when using the keyboard to select the option and twice when using the mouse.
Yes. I believe Java is doing something wrong here. Based on the fact that you have tried multiple Java versions, the issue seems not to be a Java bug. My guess would be that you have some configuration causing the issue (some sort of combination of OS settings or installed software). If there is something Ghidra is doing to break Java, then we can fix that. If not, this may be something that you have to fix external to Java / Ghidra.
Unfortunately, diagnosing focus issues is difficult and even more so if we cannot reproduce the issue.
Added several Msg.debug
to propertyChange
and in the mouse version 3 additional permanentFocusOwner
property messages appear that have the InputDialog
as the newValue
.
FYI, prior to those 3 messages, 2 others from windowActivated
occurred (and that is what's setting the focus correctly). How do you determine what triggered those?
The events are being generated from within the jvm. At some point that becomes a black box.
I wonder if this has something to do with the task dialog that is appearing. That is the "Create Structure From Selection" dialog. For me, that is behind the newly opened input dialog. There may be some sort of handshake / parenting problem with when we are showing that dialog. I will see if I can change that timing and let you know if there is something you can try in that regard.
Do those windows appear in the same order in both scenarios? The initial dialog is behind the input dialog.
Yes, they do. Interesting though, although the textbox containing the default text struct
doesn't have the focus and no amount of tabbing alters that, I can press Alt+Space
to get the System Menu of the InputDialog!
I am not seeing the "Create Structure From Selection" appear in the propertyChange()
focus events. Do you see that dialog in these events?
These messages are common to keyboard or mouse activation:
DEBUG propertyChange evt=java.beans.PropertyChangeEvent[propertyName=permanentFocusOwner; oldValue=ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$CompositeTable[,0,0,755x1496,alignmentX=0.0,alignmentY=0.0,border=,flags=234881384,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_LAST_COLUMN,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=#808080,preferredViewportSize=java.awt.Dimension[width=610,height=250],rowHeight=17,rowMargin=0,rowSelectionAllowed=true,selectionBackground=#0078d7,selectionForeground=#ffffff,showHorizontalLines=false,showVerticalLines=false]; newValue=null; propagationId=null; source=java.awt.DefaultKeyboardFocusManager@1203515a] (DockingWindowManager.java:1491)
DEBUG propertyChange evt=java.beans.PropertyChangeEvent[propertyName=permanentFocusOwner; oldValue=ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$CompositeTable[,0,0,755x1496,alignmentX=0.0,alignmentY=0.0,border=,flags=234881384,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_LAST_COLUMN,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=#808080,preferredViewportSize=java.awt.Dimension[width=610,height=250],rowHeight=17,rowMargin=0,rowSelectionAllowed=true,selectionBackground=#0078d7,selectionForeground=#ffffff,showHorizontalLines=false,showVerticalLines=false]; newValue=null; propagationId=null; source=java.awt.DefaultKeyboardFocusManager@1203515a] (DockingWindowManager.java:1491)
DEBUG nfc=null (DockingWindowManager.java:1501)
DEBUG propertyChange evt=java.beans.PropertyChangeEvent[propertyName=permanentFocusOwner; oldValue=ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$CompositeTable[,0,0,755x1496,alignmentX=0.0,alignmentY=0.0,border=,flags=234881384,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_LAST_COLUMN,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=#808080,preferredViewportSize=java.awt.Dimension[width=610,height=250],rowHeight=17,rowMargin=0,rowSelectionAllowed=true,selectionBackground=#0078d7,selectionForeground=#ffffff,showHorizontalLines=false,showVerticalLines=false]; newValue=null; propagationId=null; source=java.awt.DefaultKeyboardFocusManager@1203515a] (DockingWindowManager.java:1491)
DEBUG propertyChange evt=java.beans.PropertyChangeEvent[propertyName=permanentFocusOwner; oldValue=null; newValue=ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$CompositeTable[,0,0,755x1496,alignmentX=0.0,alignmentY=0.0,border=,flags=234881384,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_LAST_COLUMN,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=#808080,preferredViewportSize=java.awt.Dimension[width=610,height=250],rowHeight=17,rowMargin=0,rowSelectionAllowed=true,selectionBackground=#0078d7,selectionForeground=#ffffff,showHorizontalLines=false,showVerticalLines=false]; propagationId=null; source=java.awt.DefaultKeyboardFocusManager@1203515a] (DockingWindowManager.java:1491)
DEBUG propertyChange evt=java.beans.PropertyChangeEvent[propertyName=permanentFocusOwner; oldValue=null; newValue=ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$CompositeTable[,0,0,755x1496,alignmentX=0.0,alignmentY=0.0,border=,flags=234881384,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_LAST_COLUMN,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=#808080,preferredViewportSize=java.awt.Dimension[width=610,height=250],rowHeight=17,rowMargin=0,rowSelectionAllowed=true,selectionBackground=#0078d7,selectionForeground=#ffffff,showHorizontalLines=false,showVerticalLines=false]; propagationId=null; source=java.awt.DefaultKeyboardFocusManager@1203515a] (DockingWindowManager.java:1491)
DEBUG nfc=ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$CompositeTable[,0,0,755x1496,alignmentX=0.0,alignmentY=0.0,border=,flags=234881384,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_LAST_COLUMN,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=#808080,preferredViewportSize=java.awt.Dimension[width=610,height=250],rowHeight=17,rowMargin=0,rowSelectionAllowed=true,selectionBackground=#0078d7,selectionForeground=#ffffff,showHorizontalLines=false,showVerticalLines=false] (DockingWindowManager.java:1501)
DEBUG dc=Structure Editor - Copy_1_of_DgnLanguageModel_0xc2_t_beforechangingfld0x26 (DRAGON) (DockingWindowManager.java:1508)
DEBUG propertyChange evt=java.beans.PropertyChangeEvent[propertyName=permanentFocusOwner; oldValue=null; newValue=ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$CompositeTable[,0,0,755x1496,alignmentX=0.0,alignmentY=0.0,border=,flags=234881384,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_LAST_COLUMN,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=#808080,preferredViewportSize=java.awt.Dimension[width=610,height=250],rowHeight=17,rowMargin=0,rowSelectionAllowed=true,selectionBackground=#0078d7,selectionForeground=#ffffff,showHorizontalLines=false,showVerticalLines=false]; propagationId=null; source=java.awt.DefaultKeyboardFocusManager@1203515a] (DockingWindowManager.java:1491)
DEBUG calling windowActivated on: docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@43005f1f,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING] : hasBeenFocused=false (DockingDialog.java:228)
DEBUG calling windowActivated, component= Editor: Create Structure From Selection; focused comp=null (DockingDialog.java:232)
These additional messages appear when using the mouse:
DEBUG calling windowActivated on: docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@43005f1f,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING] : hasBeenFocused=false (DockingDialog.java:228)
DEBUG calling windowActivated, component= Specify the Structure's Name; focused comp=docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@43005f1f,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING] (DockingDialog.java:232)
DEBUG calling request focus on: docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@43005f1f,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING] (DockingDialog.java:51)
DEBUG did focus?: true (DockingDialog.java:56)
DEBUG propertyChange evt=java.beans.PropertyChangeEvent[propertyName=permanentFocusOwner; oldValue=ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$CompositeTable[,0,0,755x1496,alignmentX=0.0,alignmentY=0.0,border=,flags=234881384,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_LAST_COLUMN,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=#808080,preferredViewportSize=java.awt.Dimension[width=610,height=250],rowHeight=17,rowMargin=0,rowSelectionAllowed=true,selectionBackground=#0078d7,selectionForeground=#ffffff,showHorizontalLines=false,showVerticalLines=false]; newValue=docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@43005f1f,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING]; propagationId=null; source=java.awt.DefaultKeyboardFocusManager@1203515a] (DockingWindowManager.java:1491)
DEBUG propertyChange evt=java.beans.PropertyChangeEvent[propertyName=permanentFocusOwner; oldValue=ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$CompositeTable[,0,0,755x1496,alignmentX=0.0,alignmentY=0.0,border=,flags=234881384,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_LAST_COLUMN,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=#808080,preferredViewportSize=java.awt.Dimension[width=610,height=250],rowHeight=17,rowMargin=0,rowSelectionAllowed=true,selectionBackground=#0078d7,selectionForeground=#ffffff,showHorizontalLines=false,showVerticalLines=false]; newValue=docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@43005f1f,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING]; propagationId=null; source=java.awt.DefaultKeyboardFocusManager@1203515a] (DockingWindowManager.java:1491)
DEBUG propertyChange evt=java.beans.PropertyChangeEvent[propertyName=permanentFocusOwner; oldValue=ghidra.app.plugin.core.compositeeditor.CompositeEditorPanel$CompositeTable[,0,0,755x1496,alignmentX=0.0,alignmentY=0.0,border=,flags=234881384,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_LAST_COLUMN,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=#808080,preferredViewportSize=java.awt.Dimension[width=610,height=250],rowHeight=17,rowMargin=0,rowSelectionAllowed=true,selectionBackground=#0078d7,selectionForeground=#ffffff,showHorizontalLines=false,showVerticalLines=false]; newValue=docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@43005f1f,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING]; propagationId=null; source=java.awt.DefaultKeyboardFocusManager@1203515a] (DockingWindowManager.java:1491)
DEBUG active window: Specify the Structure's Name
focused window: Specify the Structure's Name
focus owner: docking.widgets.dialogs.InputDialog$MyTextField[input.dialog.text.field.0,123,5,166x20,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@43005f1f,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=#000000,disabledTextColor=#6d6d6d,editable=true,margin=javax.swing.plaf.InsetsUIResource[top=2,left=2,bottom=2,right=2],selectedTextColor=#ffffff,selectionColor=#0078d7,columns=20,columnWidth=8,command=,horizontalAlignment=LEADING] (DockingDialog.java:64)
By replacing:
https://github.com/NationalSecurityAgency/ghidra/blob/e5a8f26347e480292580f252806bda9a4e49b814/Ghidra/Framework/Docking/src/main/java/docking/DockingWindowManager.java#L1772-L1777
in DockingWindowManager.doShowDialog(...)
with
Swing.runIfSwingOrRunLater(r);
it worked!
However, what's the consequence??
However, what's the consequence??
That is some of the most complicated and sensitive code in the system. We keep an uneasy truce with the way that code handles modal dialogs.
This is more information to support the idea that the modal dialog timing with the input dialog is not working correctly for you. I'll keep chewing on this.
I starting seeing odd behavior related to focus. After trying many things, I needed to update the action that shows the context menu in order for my system to start behaving again.
I'm curious is my change has any effect on your original issue. When you get a chance, edit ShowContextMenuAction
to use a Swing.runLater()
, like so:
if (focusOwner != null) {
Swing.runLater(() -> {
DockingWindowManager.showContextMenu(focusOwner);
});
}
Darn! No effect!
Just a reminder, it's the difference between pressing <Enter>
on the keyboard and clicking with the mouse to select the menu item that's causing this anomaly, not displaying the context menu initially.
I am aware of the distinction. I ran into a separate issue where my menu focus stopped working for some reason.
At this point, I am fairly confident that your particular issue has to do with the Java handshake between the various windows that get shown during window activation. My guess is that by clicking the menu item, there is a focus change in Java that keeps the handshake consistent.
To help rule out the task code vs the handshake issue, try this change inside of CreateInternalStructureAction
:
private void doCreate(TaskMonitor monitor) {
InputDialog dialog = new InputDialog("Title", "Text: ");
DockingWindowManager.showDialog(dialog);
String text = dialog.getValue();
Msg.debug(this, "Input dialog text: " + text);
try {
((StructureEditorModel) model).createInternalStructure(monitor);
}
catch (CancelledException e) {
// user cancelled
}
catch (UsrException e) {
model.setStatus(e.getMessage(), true);
}
}
I'd like to know if the new dialog that appears has focus. Also, after that dialog is shown, do any follow-on dialogs get focused correctly?
The new dialog suffers the exact same issue. However once closed, the next one's do have the correct focus.
Next test, inside of actionPerformed()
, replace this:
if (maxRow < numComponents) {
TaskLauncher.launchModal(getName(), this::doCreate);
}
with this:
if (maxRow < numComponents) {
InputDialog dialog = new InputDialog("Title", "Text: ");
DockingWindowManager.showDialog(dialog);
String text = dialog.getValue();
Msg.debug(this, "Input dialog text: " + text);
TaskLauncher.launchModal(getName(), this::doCreate);
}
As before, I'd like to know the focus behavior with this dialog and the follow-on dialogs.
This time, your new Text dialog is displayed with the focus correct. Unfortunately, subsequent dialogs fail!
Thanks for the help with this. To solve this particular issue, I plan on pulling the prompts out of the task. This should allow you to interact as needed, with the long-running work being done in a task without the need for user interaction.
I really appreciate your persistence in looikng into this. Thank you very much.
Describe the bug Inside the
Structure Editor
dialog, trying to create a sub-structure from a selection of fields opens the dialog "Specify the Structure's Name" without any keyboard focus only when using the keyboard to bring up the context menu and choosingCreate Structure from Selection
. (Using the mouse works!)To Reproduce Steps to reproduce the behavior:
Create Structure from Selection
Expected behavior The provided name (
struct
) should be immediately modifyable, just as it is when using the mouse.Screenshots N/A
Attachments N/A
Environment (please complete the following information):