<AWT Dev> [8] Review request for 7171045 [macosx] There are no enter or exit events reported against 8b39 for MouseEventsDuringDrag.

Sergey Bylokhov Sergey.Bylokhov at oracle.com
Tue Aug 28 06:57:46 PDT 2012


Hi Alexander.
Fix looks good.

28.08.2012 15:17, Alexander Scherbatiy wrote:
>
> Could you review the updated fix:
>   http://cr.openjdk.java.net/~alexsch/7171045/webrev.05/
> The comments are below:
>    - NSTrackingCursorUpdate option is removed from the 
> rolloverTrackingArea
>
> On 8/24/2012 7:00 PM, Anthony Petrov wrote:
>> src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
>>>  66     public static native CPlatformWindow 
>>> nativeGetTopmostPlatformWindowUnderMouse();
>>
>> This method must probably be private.
>       Fixed.
>
>>
>> Still, I don't see why getTopmostPlatformWindowUnderMouse() must 
>> return null when it's invoked on an embedded frame, and why the 
>> implementation should even be different at all. The mouse is a global 
>> system entity. There's either some window under the mouse, or there's 
>> not. I would still think of LWToolkit.getPlatformWindowUnderMouse(), 
>> and its implementation in LWCToolkit.
>
>      Dmitry, who is a responsible person for the 
> CPlatformEmbeddedFrame, said that the implementation of the 
> getPlatformWindowUnderMouse() method could be different for applets.
>      So the getPlatformWindowUnderMouse() method implementation will 
> be filled as a separated issue and fixed by Dmitry.
>
>>
>> Also, the logic in LWWindowPeer lines 722-743 seems to be overly 
>> complicated (as well as the whole dispatchMouseEvent() method). E.g., 
>> if the LWWindowPeer manages an embedded frame, we get 
>> topmostWindowPeer == this at line 730, and thus always go through the 
>> 'true' branch of if() at line 733, even though actually the mouse 
>> pointer can be located over some other window at the moment (e.g. 
>> over a popup window opened by an applet).
>     I updated the topmostWindowPeer variable creation so it now can 
> have only the topmost window under mouse value  or null and added a 
> comment that the (topmostWindowPeer == null )
>     condition should be removed after the 
> getPlatformWindowUnderMouse() method implementation in the 
> CPlatformEmbeddedFrame class.
>     For now the (topmostWindowPeer == null ) condition allows to track 
> the mouse enter/exit components events as it was before the fix.
>>
>> Overall, it's really difficult to understand what is going on there. 
>> I've spent half an hour reading the code and am still not sure if I 
>> get it right. Why does LWWindowPeer even care about the 
>> EXITED/ENTERED events for components? Shouldn't this code belong to 
>> LWComponentPeer? Or even the shared code? How do Swing components in 
>> regular Swing apps get the ENTERED/EXITED events then? Why can't we 
>> use the same approach for LWAWT?
>     Swing controls have Container in  a parent class hierarchy. The 
> Container class has the LightweightDispatcher dispatcher which allows 
> to track mouse moving from one component to another and generate 
> necessary mouse enter/exit events.
>    AWT controls have Component class as a parent and do not have the 
> dispatcher. So moving/dragging a mouse from one AWT control to another 
> does not generate necessary mouse events.
>
>   The aim of the fix is not redesigning current architecture. It just 
> adds checking a case where a mouse is dragged from one window to 
> another and so the first window which gets the mouse drag events is 
> not the real window for which component enter/exit events should be 
> generated.
>
>    Thanks,
>    Alexandr.
>
>>
>> -- 
>> best regards,
>> Anthony
>>
>> On 8/24/2012 5:53 PM, Alexander Scherbatiy wrote:
>>>
>>> Could you review the updated fix:
>>>   http://cr.openjdk.java.net/~alexsch/7171045/webrev.04/
>>> The comments are below:
>>>
>>> On 8/23/2012 4:51 PM, Anthony Petrov wrote:
>>>> Hi Alexandr,
>>>>
>>>> 1. In synthesizeMouseEnteredExitedEventsForAllWindows, can we 
>>>> iterate through app's windows only once and send both Exited and 
>>>> Entered events where needed?
>>>     Now, when we do not care about the order of the mouse enter/exit 
>>> events generation it is possible to do. I have updated the code.
>>>>
>>>> 2. Also, it looks like nativeSynthesizeMouseEnteredExitedEvents no 
>>>> longer requires a window pointer as an argument.
>>>        Fixed.
>>>>
>>>> 3. Here's a major concern: the LWWindowPeer (and other LW* classes) 
>>>> should never import C* classes. Instead you should've added a new 
>>>> method to the PlatformWindow interface, and used it from 
>>>> LWWindowPeer. The CPlatformWindow should've implemented this 
>>>> method, and called an appropriate native method from there. In this 
>>>> case, however, you actually need a static method, so it'd better be 
>>>> part of the LWToolkit interface, and implemented in the LWCToolkit 
>>>> class instead.
>>>      I see.  It seems that the getTopmostWindowUnderMouse method 
>>> implementation is different for the CPlatformWindow and for the 
>>> CPlatformEmbeddedFrame.
>>>      So I added the getTopmostPlatformWindowUnderMouse method to the 
>>> PlatformWindow  interface.
>>>
>>>     Thanks,
>>>     Alexandr.
>>>
>>>>
>>>> -- 
>>>> best regards,
>>>> Anthony
>>>>
>>>> On 08/23/12 15:40, Alexander Scherbatiy wrote:
>>>>>
>>>>> Could someone review the fix?
>>>>>
>>>>> Thanks,
>>>>> Alexandr.
>>>>>
>>>>> On 8/10/2012 6:00 PM, Alexander Scherbatiy wrote:
>>>>>>
>>>>>> Could you review the updated fix:
>>>>>> http://cr.openjdk.java.net/~alexsch/7171045/webrev.02/
>>>>>>
>>>>>> The comments are below:
>>>>>>
>>>>>> On 8/7/2012 6:47 PM, Mike Swingler wrote:
>>>>>>> I noticed that, NSWindow's windowNumber is NSInteger, which is 32
>>>>>>> bits wide on 32-bit and 64 bits wide on 64-bit. Chopping that to a
>>>>>>> simple 32 bit int is probably not what you intended to do.
>>>>>> fixed.
>>>>>>> Also, have you considered simply calling -[NSWindow
>>>>>>> setAcceptsMouseMovedEvents:YES] in -[AWTView initWithRect:], and 
>>>>>>> then
>>>>>>> removing the calls that flip it on and off in -[AWTView
>>>>>>> mouseEntered:] and -[AWTView mouseExited"]? This would also 
>>>>>>> require a
>>>>>>> change in
>>>>>>> Java_sun_lwawt_macosx_CPlatformWindow_nativeSetNSWindowBounds(),
>>>>>>> which has a comment that states it only turns on mouse moved events
>>>>>>> if the window is currently under the mouse.
>>>>>> I tried it. The result that I got is that a dragging mouse from one
>>>>>> window to another does not generate mouse enter/exit events on the
>>>>>> second window in case when tracking rect is used and the
>>>>>> acceptsMouseMovedEvents flag is always set to YES.
>>>>>>
>>>>>>> I would think that AppKit should be more than happy to send you
>>>>>>> mouse-over/enter/exited events as long as you say you want them. 
>>>>>>> Was
>>>>>>> this approach tried and didn't work for some reason?
>>>>>>>> Hi, Alexander.
>>>>>>>> Probably all this stuff can be simplified? Can you try to change
>>>>>>>> TrackingRect to TrackingArea with appropriate flags like
>>>>>>>> NSTrackingEnabledDuringMouseDrag etc.
>>>>>> I changed the TrackingRect to TrackingArea in the updated fix. It 
>>>>>> now
>>>>>> generates the mouse enter/exit events on the second window during 
>>>>>> drag.
>>>>>> So it is not necessary to generates such events from our side.
>>>>>>
>>>>>> The getTopmostWindowUnderMouse is necessary to handle mouse 
>>>>>> enter/exit
>>>>>> events for component in case when a mouse is dragged from one window
>>>>>> to another.
>>>>>> Where the second window contains it's own components and the only 
>>>>>> way
>>>>>> to know about tracking over them are drag events which receives the
>>>>>> first window.
>>>>>>
>>>>>> I think that the LWWindowPeer class code can be simplified if we
>>>>>> assume that window mouse enter/exit events are always come to the
>>>>>> current window.
>>>>>> So the component mouse enter/exit events can be tracked only in the
>>>>>> current or topmost window.
>>>>>> For this case I separated the global lastCommonMouseEventPeer 
>>>>>> which is
>>>>>> necessary for the cursor manager and the local lastMouseEventPeer.
>>>>>>
>>>>>> According to the specification: The proper order of mouse-entered 
>>>>>> and
>>>>>> mouse-exited events received by tracking-area objects in an
>>>>>> application cannot be guaranteed.
>>>>>> https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/TrackingAreaObjects/TrackingAreaObjects.html 
>>>>>>
>>>>>>
>>>>>> So it seems it is not possible to have one lastMouseEventPeer 
>>>>>> instead
>>>>>> of two: lastCommonMouseEventPeer and lastMouseEventPeer.
>>>>>>
>>>>>> And there are possible situations that we can receive mouse drag 
>>>>>> event
>>>>>> between enter and exit.
>>>>>> To handle this the isMouseOver flag is added to the LWWindowPeer
>>>>>> class. So the component mouse enter/exit events are not generated if
>>>>>> the window mouse exited event is received and window mouse 
>>>>>> entered is
>>>>>> not.
>>>>>>
>>>>>> There is the test:
>>>>>> test/java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java
>>>>>> It shows that even using the TrackingArea some mouse enter/exit 
>>>>>> events
>>>>>> are not generateed in the following cases:
>>>>>> - window is created under the mouse
>>>>>> - window changes it's bounds so it becomes under the mouse
>>>>>>
>>>>>> For this cases it still necessary to generate mouse enter/exit 
>>>>>> events
>>>>>> from our side.
>>>>>> I just moved the related code to one method
>>>>>> synthesizeMouseEnteredExitedEventsForAllWindows.
>>>>>>
>>>>>> Thanks,
>>>>>> Alexandr.
>>>>>>
>>>>>>>> 07.08.2012 15:17, Alexander Scherbatiy wrote:
>>>>>>>>> bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7171045
>>>>>>>>> webrev: http://cr.openjdk.java.net/~alexsch/7171045/webrev.01/
>>>>>>>>>
>>>>>>>>> This is a regression after the fix 7154048 [macosx] At least drag
>>>>>>>>> twice, the toolbar can be dragged to the left side.
>>>>>>>>>
>>>>>>>>> In the case where a toolbar is created under a mouse and it is
>>>>>>>>> dragged over the initial window the mouse enter/exit events 
>>>>>>>>> should
>>>>>>>>> not be generated for the components which are under the toolbar.
>>>>>>>>>
>>>>>>>>> The current fix is supposed to solve this regression and also to
>>>>>>>>> fix generation of mouse enter/exit events for all cases where a
>>>>>>>>> mouse is dragged from one window to another or a new window is
>>>>>>>>> created under a mouse (like it is implemented for toolbar).
>>>>>>>>>
>>>>>>>>> Let's see the following cases
>>>>>>>>> 1) Mouse is dragged from a window and back to the same window.
>>>>>>>>> The Mac OS X system generates a mouse exit event only the first
>>>>>>>>> time when a mouse is dragged from a window and does not generate
>>>>>>>>> mouse enter/exit events next times during one drag trace.
>>>>>>>>>
>>>>>>>>> 2) Mouse is dragged from one window to another.
>>>>>>>>> The Mac OS X system does not generate mouse enter/exit events for
>>>>>>>>> the second window.
>>>>>>>>>
>>>>>>>>> 3) Mouse is dragged from one window to another and released.
>>>>>>>>> In this case the Mac OS X system generates mouse enter event for
>>>>>>>>> the second window only after releasing the mouse.
>>>>>>>>>
>>>>>>>>> 4) Clicking on window creates a new window after that the new
>>>>>>>>> window is dragged (toolbar dragging).
>>>>>>>>>
>>>>>>>>> However the Java system generates mouse enter/exit events each 
>>>>>>>>> time
>>>>>>>>> when a mouse is dragged over any window.
>>>>>>>>>
>>>>>>>>> To fix this the following methods are introduced:
>>>>>>>>> - Get topmost window under mouse
>>>>>>>>> - Synthesize mouse enter/exit events for all windows
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> The dispatchMouseEvent method from the LWWindowPeer class is
>>>>>>>>> handled previous and next components and is able to generate 
>>>>>>>>> mouse
>>>>>>>>> enter/exit events for them.
>>>>>>>>> However the the AWTView native class contains isMouseOver flag
>>>>>>>>> which value becomes inconsistent if we do not updated it. Because
>>>>>>>>> of this the fix generates the mouse enter/exit window events 
>>>>>>>>> on the
>>>>>>>>> native side.
>>>>>>>>>
>>>>>>>>> Generating mouse enter/exit events always should be in order 
>>>>>>>>> where
>>>>>>>>> mouse exit events are generated before the mouse enter events.
>>>>>>>>>
>>>>>>>>> The synthesizeMouseEnteredExitedEventsForAllWindows method 
>>>>>>>>> tries to
>>>>>>>>> generate mouse enter/exit events for all windows during mouse 
>>>>>>>>> drag
>>>>>>>>> or window creation/window bounds changing.
>>>>>>>>> However only those windows which isMouseOver flag is differ from
>>>>>>>>> the isTopMostWindowUnderMouse state are affected.
>>>>>>>>> This method also tries to generate both mouse enter and exit 
>>>>>>>>> event
>>>>>>>>> for the same window but only one of them can be applicable 
>>>>>>>>> because
>>>>>>>>> the isTopMostWindowUnderMouse state is not changed for these 
>>>>>>>>> calls.
>>>>>>>>>
>>>>>>>>> So the window enter/exit events now are always generated from the
>>>>>>>>> native system and component enter/exit events are generated in 
>>>>>>>>> the
>>>>>>>>> LWWindowPeer class.
>>>>>>>>>
>>>>>>>>> LWWindowPeer class now uses three links to components: current,
>>>>>>>>> last and topmostUnderMouse. All of them are necessary because in
>>>>>>>>> case when a mouse is dragged from one window to another the 
>>>>>>>>> current
>>>>>>>>> component receives drag events and last and topmostUnderMouse 
>>>>>>>>> links
>>>>>>>>> handle components mouse exit/enter events on the second window.
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Alexandr.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>> -- 
>>>>>>>> Best regards, Sergey.
>>>>>>>>
>>>>>>
>>>>>
>>>
>


-- 
Best regards, Sergey.



More information about the macosx-port-dev mailing list