Hi Semyon,

> On 5 Oct 2017, at 17:13, Semyon Sadetsky <semyon.sadet...@oracle.com> wrote:
> 
> Hi Dmitriy,
> 
> On 10/05/2017 07:25 AM, Dmitry Markov wrote:
>> Hi Semyon,
>> 
>> Actually the most recent focus owner is updated during invocation of 
>> setEnabled(), setFocusable() and setVisible(). Please find the details below:
>>  - Component.setEnabled(false), (i.e. disable a component) - 
>> setEnabled(false) -> Component.this.setEnabled(false) -> enable(false) -> 
>> disable() -> KeyboardFocusManager.clearMostRecentFocusOwner()
>>  - Component.setFocusable(false), (i.e. make a component non-focusable) - 
>> setFocusable(false) -> transferFocus() and 
>> KeyboardFocusManager.clearMostRecentFocusOwner()
>>  - Component.setVisible(false), (i.e. make a component invisible) - 
>> setVisible(false) -> Component.this.setVisible(false) -> show(false) -> 
>> hide() -> clearMostRecentFocusOwnerOnHide() and transferFocus()
>> 
>> So the most recent focus owner is always up to date. I am sorry, but looks 
>> like it is not necessary to perform checks such as isShowing() and 
>> canBeFocusOwner() before we set some value to restoreFocusTo. These checks 
>> are implicitly performed before usage of restoreFocusTo and I believe that 
>> is enough even for concurrent execution. What do you think?
> Yes, this makes sense. I'm only not sure about the case when a parent 
> component is made invisible and the most recent focus owner is cleared for 
> the parent component but not for its child components. So all the child 
> components will start to return isShowing() false (e.g. non-focusable) but 
> any of them still may be set as most recent focus owner. This makes the 
> isShowing() check mandatory for component returned by 
> getMostRecentFocusOwner(). 
> 
If a parent component, (i.e. container) is made invisible, the most recent 
focus owner is cleared for its child components too, see implementation of 
clearMostRecentFocusOwnerOnHide() in Container class for details. So I do not 
think that it is really necessary to invoke isShowing() for the component 
returned by getMostRecentFocusOwner().

Thanks,
Dmitry
> --Semyon
>> 
>> Thanks,
>> Dmitry 
>>> On 4 Oct 2017, at 17:23, Semyon Sadetsky <semyon.sadet...@oracle.com 
>>> <mailto:semyon.sadet...@oracle.com>> wrote:
>>> 
>>> Hi Dmitry,
>>> 
>>> If you make a detailed look on the Component class methods like 
>>> setEnables(), setFocusable() and setVisible() the most recent focus owner 
>>> is cleared or transferred only after the component is made non-focusable. 
>>> Since the fix is aimed for concurrent scenarios the recheck actually makes 
>>> sens.  
>>> Also it would be more correct always trying to determine the first 
>>> focusable component in traversal order before before the attempt to set 
>>> focus owner as it is done in restoreFocus(Window aWindow, Component  
>>> boolean clearOnFailure):
>>> 
>>>                 if (!toFocus.isShowing() || !toFocus.canBeFocusOwner()) {
>>>                     toFocus = toFocus.getNextFocusCandidate();
>>>                 }
>>> otherwise when focus is restored to actually non-focusable component the 
>>> final focus owner may become null while the next component in container 
>>> traversal order is expected to have the input focus.
>>> --Semyon
>>> 
>>> On 10/04/2017 03:25 AM, Dmitry Markov wrote:
>>>> Hi Sergey,
>>>> 
>>>> Good catch!
>>>> Actually we check restoreFocusTo before its usage, (i.e. we compare 
>>>> restoreFocusTo with most resent focus owner for the window; most recent 
>>>> focus owner is visible and focusable, otherwise it is removed from recent 
>>>> focus owners map).
>>>> So the checks before assignment are not really necessary. I updated the 
>>>> fix (reverted it to the previous version). Please find webrev here: 
>>>> http://cr.openjdk.java.net/~dmarkov/8155197/webrev.03/ 
>>>> <http://cr.openjdk.java.net/%7Edmarkov/8155197/webrev.03/>
>>>> 
>>>> Thanks,
>>>> Dmitry
>>>>> On 3 Oct 2017, at 18:30, Sergey Bylokhov <sergey.bylok...@oracle.com 
>>>>> <mailto:sergey.bylok...@oracle.com>> wrote:
>>>>> 
>>>>> Hi, Dmitry.
>>>>> If this check is valid then probably the same check should be added to 
>>>>> restoreFocus()? before:
>>>>> #173 restoreFocusTo = toFocus;
>>>>> 
>>>>> But as it was mentioned before, the component can become 
>>>>> non-visible/non-focusable at any point, for example after this check but 
>>>>> before the assignment. And instead of data validation before assignment 
>>>>> we should check them before use. As far as I understand we already do 
>>>>> this, all usages of                             restoreFocusTo are a 
>>>>> checks == or != to some other component which is visible and focusable, 
>>>>> isn't it?
>>>>> 
>>>>> On 10/3/17 08:23, Dmitry Markov wrote:
>>>>>> Hi Semyon,
>>>>>> I have updated the fix based on your suggestion. The new version is 
>>>>>> located at http://cr.openjdk.java.net/~dmarkov/8155197/webrev.02/ 
>>>>>> <http://cr.openjdk.java.net/%7Edmarkov/8155197/webrev.02/>
>>>>>> Also I slightly modified the test to simplify it.
>>>>>> Thanks,
>>>>>> Dmitry
>>>>>>> On 2 Oct 2017, at 18:32, Semyon Sadetsky <semyon.sadet...@oracle.com 
>>>>>>> <mailto:semyon.sadet...@oracle.com> <mailto:semyon.sadet...@oracle.com 
>>>>>>> <mailto:semyon.sadet...@oracle.com>>> wrote:
>>>>>>> 
>>>>>>> Hi Dmitry,
>>>>>>> 
>>>>>>>>> Actually the parent frame doesn't own the input focus when the issue 
>>>>>>>>> happens. The focus is on the dialog already and when FOCUS_GAINED 
>>>>>>>>> event comes for the dialog the KFM discovers that the dialog should 
>>>>>>>>> not have the focus and rejects it in line 588 of the 
>>>>>>>>> DefaultKeyboardFocusManager:
>>>>>>>>> 
>>>>>>>>>                             restoreFocus(fe, newFocusedWindow);
>>>>>>>>> 
>>>>>>>>> This happens when the dialog became non-focusable (non-visible) after 
>>>>>>>>> the focus request is sent, but before the corresponding FOCUS_GAINED 
>>>>>>>>> event is handled on the EDT. In this case the focus is directly 
>>>>>>>>> restored to the previously focused window which doesn't have the 
>>>>>>>>> focus at this moment and input focus cannot be requested to one of 
>>>>>>>>> its components synchronously.
>>>>>>>>> Please confirm whether you agree on the root cause of the bug.
>>>>>>>>> 
>>>>>>>> You are right. I agree with your evaluation.
>>>>>>> Thanks.
>>>>>>> Before setting the restoreFocusTo to toFocus in line 190 I would 
>>>>>>> recheck for toFocus.isShowing() && toFocus.canBeFocusOwner() once again 
>>>>>>> because the component can be made non-focusable concurrently.
>>>>>>> 
>>>>>>> --Semyon
>>>>>>> 
>>>>>>> 
>>>>> 
>>>>> 
>>>>> -- 
>>>>> Best regards, Sergey.
>>>> 
>>> 
>> 
> 

Reply via email to