Bug #10760
Mouse events should not be dispatched while a combo box drop-down is open.
100%
Related issues
History
#1 Updated by Paula Păstrăguș 9 months ago
Testcase:
DEFINE VARIABLE roomNumber AS CHARACTER
LABEL "Room Number"
VIEW-AS COMBO-BOX INNER-LINES 5
LIST-ITEMS "101","102","203","204"
//DROP-DOWN
SIZE 16 BY 1 NO-UNDO.
def var radio as char view-as radio-set radio-buttons
"item 1", "1",
"item 2", "2".
def var combo as char initial "Item 0"
view-as combo-box list-items
"Item 0",
"Item 1",
"Item 2".
def var f1 as char.
def var tg as logical.
def frame fMain
roomNumber combo f1
tg view-as toggle-box
radio.
ON ENTRY of combo do:
message "entry second combo".
end.
ON ENTRY of f1 do:
MESSAGE "entry fill-in".
end.
ON ENTRY of tg do:
MESSAGE "entry toggle-box".
end.
ON ENTRY of radio do:
MESSAGE "entry radio-set".
end.
current-window:WIDTH-CHARS = 100.
enable all with frame fMain.
wait-for close of current-window.
I included several widget types to check whether the issue was generic, and it appears that it is. The problem can be reproduced by clicking the first combo box (which opens the drop-down), and then clicking on any other widget.
In 4GL, mouse events are not dispatched while a drop-down is active. However, in FWD, these events are still emitted, causing the screen value of some widgets to be also affected + other side effects (like emitting entry events).
#2 Updated by Paula Păstrăguș 9 months ago
- Status changed from New to WIP
- Assignee set to Paula Păstrăguș
#3 Updated by Paula Păstrăguș 9 months ago
In this case, an approach based on simply checking whether the combo box drop-down is visible and skipping mouse event dispatch wouldn’t work, since we still need to handle mouse events for the active drop-down, otherwise, clicking on its items wouldn’t be possible.
We also need to ensure that the MOUSE_RELEASED + MOUSE_CLICKED events continues to be dispatched for the current drop-down. These were the challenges I encountered while implementing the solution.
#4 Updated by Delia Mitric 9 months ago
- Related to Bug #10801: COMBO-BOX issues added
#5 Updated by Radu Apetrii 8 months ago
- Assignee changed from Paula Păstrăguș to Delia Mitric
Delia, please work on this next. It would be really good to fully solve #10676 (and we need this task to do so). Thank you!
#6 Updated by Delia Mitric 8 months ago
I wonder if the only solution is to omit sending the mouse events (and make sure these events are still generated for the current drop-down).
I was thinking if it's possible not to process events for other widgets if a drop-down menu of a combo-box is currently active (and the combo-box has the focus).
Or maybe there are other ideas...
#7 Updated by Paula Păstrăguș 8 months ago
At one point, I considered implementing a solution similar to how events are handled for the active window while being ignored for inactive ones. The difficulty is that the combo-box dropdown is an OverlayWindow (which could be useful), whereas the combo-box widget itself belongs to the parent window.
A possible starting point would be to introduce a new method in WindowManager, such as isMenuDisplayed, to detect when a combo box dropdown (OverlayWindow) is visible and adjust the logic accordingly.
#8 Updated by Paula Păstrăguș 8 months ago
Next, you can experiment with a single widget (e.g., a fill-in) to verify that mouse events are not processed while the drop-down is active, the focus behaves correctly (please confirm this in 4GL, I believe it remains on the combo box), and the drop-down closes properly.
If this works, the next step would be to identify a central linking point, so you don’t need to override the mouse event methods of every widget just to prevent event processing in that scenario.
#9 Updated by Delia Mitric 8 months ago
- File base_patch.patch
added - % Done changed from 0 to 10
- reviewer Hynek Cihlar added
Hynek, can you verify this patch, please?
It could be a basis for the fix (and it can certainly suffer more changes :) ).
This patch "blocks" the MOUSE-PRESSED/RELEASED/CLICKED events in WindowManager when a drop-down menu is active (an Overlay Window as Paula said).
I also noticed that if we only block mouse events, the issue persists because of the FOCUS event which is still being processed. I also "blocked" the focus event processing, just for the combo-box widget for now, but if you consider it's okay, I'll continue with other widgets/to find a common point to handle this.
(One more thing to add is to block also the processing of the ENTRY event.)
I tested the initial Counteract issue and it's solved with this patch.
In any case.. I'll continue to investigate this, as there may be other aspects that haven't been found.
#10 Updated by Delia Mitric 8 months ago
- % Done changed from 10 to 80
I've found another approach to treat the issue.
The mouse events are blocked in ThinClient.processProgressEvent method.
Now, no ENTRY event is triggered and the focus isn't changed if a DROP DOWN is currently displayed and the mouse event's source is another widget than a COMBO-BOX or a different COMBO-BOX than the focused one.
This is the patch: Show
#11 Updated by Hynek Cihlar 8 months ago
Yes, the second patch looks better. A few points.
- The drop-down is dismissed on mouse down (at least it does in OE). Hold the mouse down to see this. So should the if branch be executed on mouse relased and mouse pressed?
- Is
isDropDownDisplayedeven needed whenisDropDownActiveis checked? Btw.isDropDownDisplayedhas a misleading name, it only checks for overlay windows. - Does it make sense to also call
consume()on the mouse down event?
#12 Updated by Delia Mitric 8 months ago
Hynek Cihlar wrote:
Yes, the second patch looks better. A few points.
- The drop-down is dismissed on mouse down (at least it does in OE). Hold the mouse down to see this. So should the if branch be executed on mouse relased and mouse pressed?
Yes, the drop-down menu is dismissed at MOUSE-DOWN in 4GL.
- Is
isDropDownDisplayedeven needed whenisDropDownActiveis checked? Btw.isDropDownDisplayedhas a misleading name, it only checks for overlay windows.
We need to know if a drop-down is active when we treat mouse events for every widget in order to see if we block the event or not. isDropDownActive is useful for a COMBO-BOX widget (other than the one containing the displayed drop-down), but what if we have a FILL-IN widget? We should block the mouse event to not produce side-effects.
I'll try to modify the implementation of isDropDownDisplayed in order to check just for drop-down overlay windows :).
- Does it make sense to also call
consume()on the mouse down event?
I'll add it.
Thank you :) !
#14 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
I'll try to modify the implementation of
isDropDownDisplayedin order to check just for drop-down overlay windows :).
Sorry, I didn't realize this earlier. In TC we already now the combo box with active drop-down, see the methods TC.setActiveComboBox and TC.resetActiveComboBox. So the new WindowManager method is not needed.
#15 Updated by Delia Mitric 8 months ago
Hynek Cihlar wrote:
Delia Mitric wrote:
I'll try to modify the implementation of
isDropDownDisplayedin order to check just for drop-down overlay windows :).Sorry, I didn't realize this earlier. In
TCwe already now the combo box with active drop-down, see the methodsTC.setActiveComboBoxandTC.resetActiveComboBox. So the newWindowManagermethod is not needed.
Oh, okay. Thank you!
I've removed the isDropDownDisplayed method from WindowManager and committed again, rev. 16279.
Please review :)
#16 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
Hynek Cihlar wrote:
Delia Mitric wrote:
I'll try to modify the implementation of
isDropDownDisplayedin order to check just for drop-down overlay windows :).Sorry, I didn't realize this earlier. In
TCwe already now the combo box with active drop-down, see the methodsTC.setActiveComboBoxandTC.resetActiveComboBox. So the newWindowManagermethod is not needed.Oh, okay. Thank you!
I've removed the
isDropDownDisplayedmethod fromWindowManagerand committed again, rev. 16279.
Please review :)
It looks good. Is the condition:
(legacyMouseSource instanceof ComboBoxGuiImpl &&
!((ComboBoxGuiImpl) legacyMouseSource).isDropDownActive()) ||
!(legacyMouseSource instanceof ComboBoxGuiImpl)
still needed?
#17 Updated by Delia Mitric 8 months ago
Hynek Cihlar wrote:
It looks good. Is the condition:
[...]
still needed?
It is needed because we should process MOUSE_PRESSED for the current active DROP-DOWN, but not for an another COMBO-BOX or a different widget than the focused COMBO-BOX.
If we remove it, will block also the mouse event for the active combo-box.
#19 Updated by Delia Mitric 8 months ago
One more point:
During testing the app I've noticed that if we press a button while a drop-down is active, the effects of choosing the button are realized, while in the original app they're not. Tested with trunk and with 10760a patch and this behavior remains the same.
#20 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
I've changed it to a simpler one:
[...]
But if there can be only a single active drop-down in the running app then does it really need to be tested further? I'm pretty sure your code will run fine as is, but if it could be simplified even further, let's do it.
#21 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
One more point:
During testing the app I've noticed that if we press a button while a drop-down is active, the effects of choosing the button are realized,
Shouldn't this use case be also in-scope?
#22 Updated by Delia Mitric 8 months ago
Hynek Cihlar wrote:
Delia Mitric wrote:
One more point:
During testing the app I've noticed that if we press a button while a drop-down is active, the effects of choosing the button are realized,Shouldn't this use case be also in-scope?
Yes.
I didn't managed to find a testcase yet. There are more specific scenarios that come from different application contexts. I'll try to find one which includes a combo-box and a button and behaves like in the scenario I've found.
#24 Updated by Delia Mitric 8 months ago
Delia Mitric wrote:
One more point:
During testing the app I've noticed that if we press a button while a drop-down is active, the effects of choosing the button are realized, while in the original app they're not. Tested with trunk and with 10760a patch and this behavior remains the same.
I forgot to mention that this happens just on the web app. In the Swing application, it works as expected with the 10760a patch.
#25 Updated by Delia Mitric 8 months ago
Delia Mitric wrote:
One more point:
During testing the app I've noticed that if we press a button while a drop-down is active, the effects of choosing the button are realized, while in the original app they're not. Tested with trunk and with 10760a patch and this behavior remains the same.
The problem here is that: CHOOSE event of the button is dispatched by MOUSE-CLICKED mouse-event, but when MOUSE_CLICKED is treated, the drop-down menu is already hidden (from the MOUSE_PRESSED event).
So, it's necessary to block the MOUSE_CLICKED event, but having the information about the active drop-down menu.
#27 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
I was thinking to add a flag in
ThinClientin order to mark if a drop-down was active at theMOUSE_PRESSEDevent for a button in order to "block" theMOUSE_CLICKEDevent (for the same button, for sure :) ).
Beware choose is triggered on mouse up, not click. A flag in TC shoud be fine, but make sure it is cleared reliably. For example when you press mouse button then mouse move outside FWD and release the button outside. Please test both Web GUI and Swing GUI.
#30 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
Hynek Cihlar wrote:
Beware choose is triggered on mouse up, not click.
Okay, but I've tested by blocking the
MOUSE UPevent (for the button), and theCHOOSEevent is still treated. If I block theMOUSE_CLICKEDevent, all works as expected.
Sorry, can you explain? Are you saying there is a test case in OpenEdge where button is chosen on mouse click (not up)?
#31 Updated by Delia Mitric 8 months ago
Hynek Cihlar wrote:
Delia Mitric wrote:
Hynek Cihlar wrote:
Beware choose is triggered on mouse up, not click.
Okay, but I've tested by blocking the
MOUSE UPevent (for the button), and theCHOOSEevent is still treated. If I block theMOUSE_CLICKEDevent, all works as expected.Sorry, can you explain? Are you saying there is a test case in OpenEdge where button is chosen on mouse click (not up)?
I'm saying that we should block MOUSE_CLICK event for a button if a drop down was active at MOUSE_PRESSED of the button. If we block MOUSE_RELEASED there is no effect, so the CHOOSE event is still dispatched and treated.
#32 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
Hynek Cihlar wrote:
Delia Mitric wrote:
Hynek Cihlar wrote:
Beware choose is triggered on mouse up, not click.
Okay, but I've tested by blocking the
MOUSE UPevent (for the button), and theCHOOSEevent is still treated. If I block theMOUSE_CLICKEDevent, all works as expected.Sorry, can you explain? Are you saying there is a test case in OpenEdge where button is chosen on mouse click (not up)?
I'm saying that we should block
MOUSE_CLICKevent for a button if a drop down was active atMOUSE_PRESSEDof the button. If we blockMOUSE_RELEASEDthere is no effect, so theCHOOSEevent is still dispatched and treated.
Even in the case when the mouse is pressed, held, released (no click)?
#33 Updated by Delia Mitric 8 months ago
Hynek Cihlar wrote:
Even in the case when the mouse is pressed, held, released (no click)?
So, if we press on the button, held it and released the mouse "outside" the button, no click event is dispatched. I've checked and in that case, the mouseSource for MOUSE_RELEASED event is still the button.
In that case, we don't have to block anything because the click was not dispatched, so the CHOOSE event of the button will not be triggered.
This behavior is the same in 4GL. The CHOOSE event is triggered at click event.
Please see this OE testcase, press on the button, held and released outside the button. No "button was chosen" is displayed.
def button btn.
def frame f
btn
with 1 down size 30 by 30.
enable all with frame f.
on choose of btn do:
message "button was chosen".
end.
wait-for close of current-window.
Another point, I've noticed that the order of these events is: MOUSE_PRESSED -> MOUSE_RELEASED -> [MOUSE_CLICKED]
#34 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
Hynek Cihlar wrote:
Even in the case when the mouse is pressed, held, released (no click)?
So, if we press on the button, held it and released the mouse "outside" the button, no click event is dispatched.
No click should be dispatched even if you release the mouse button while still cursor in the button.
#35 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
Another point, I've noticed that the order of these events is:
MOUSE_PRESSED->MOUSE_RELEASED-> [MOUSE_CLICKED]
Do you see this in OE or FWD? Does the behavior differ? Is this a regression or also happens in trunk?
#36 Updated by Delia Mitric 8 months ago
Hynek Cihlar wrote:
Delia Mitric wrote:
Another point, I've noticed that the order of these events is:
MOUSE_PRESSED->MOUSE_RELEASED-> [MOUSE_CLICKED]Do you see this in OE or FWD? Does the behavior differ? Is this a regression or also happens in trunk?
I see this is FWD in cases when release is made while the cursor is on the button.
#37 Updated by Delia Mitric 8 months ago
In OE, what is clear is if the mouse is released with the cursor outside of the button, then no CHOOSE event is triggered.
If the release is made while the cursor is on the button then CHOOSE event is triggered in OE. This may mean that CHOOSE is triggered at click event, but I'm not sure if this is the real OE behavior.
#38 Updated by Delia Mitric 8 months ago
Hynek Cihlar wrote:
Do you see this in OE or FWD? Does the behavior differ? Is this a regression or also happens in trunk?
To be clear: MOUSE_PRESSED -> MOUSE_RELEASED -> [MOUSE_CLICKED] sequence is saw with trunk every time we press and release the mouse while the cursor is on the button.
#39 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
Hynek Cihlar wrote:
Do you see this in OE or FWD? Does the behavior differ? Is this a regression or also happens in trunk?
To be clear:
MOUSE_PRESSED -> MOUSE_RELEASED -> [MOUSE_CLICKED]sequence is saw with trunk every time we press and release the mouse while the cursor is on the button.
I see now. The reason you need to prevent the click event is that it is sent in FWD while it should not be (long hold should not produce click, only mouse release event).
#40 Updated by Delia Mitric 8 months ago
Hynek Cihlar wrote:
Delia Mitric wrote:
Hynek Cihlar wrote:
Do you see this in OE or FWD? Does the behavior differ? Is this a regression or also happens in trunk?
To be clear:
MOUSE_PRESSED -> MOUSE_RELEASED -> [MOUSE_CLICKED]sequence is saw with trunk every time we press and release the mouse while the cursor is on the button.I see now. The reason you need to prevent the click event is that it is sent in FWD while it should not be (long hold should not produce click, only mouse release event).
Yes :). Sorry if what I've tried to explain was a little confusing..
If the mouse is pressed and released immediately, click event should be dispatched, right? In that case, we should prevent the click event if the drop-down was active at MOUSE_PRESSED event.
Also, should I open a new issue for "long hold should not produce click, only mouse release event"? If this will be fixed, we have to prevent also MOUSE_RELEASED for a button if at MOUSE_PRESSED a drop-down was active (just for scenarios with long hold).
#41 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
Also, should I open a new issue for "long hold should not produce click, only mouse release event"? If this will be fixed, we have to prevent also
MOUSE_RELEASEDfor a button if atMOUSE_PRESSEDa drop-down was active (just for scenarios with long hold).
Only if it also means the legacy events @MOUSE-*-CLICK* are also triggered in FWD and are not in OE.
#42 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
Yes :). Sorry if what I've tried to explain was a little confusing..
No, I think my brain was a bit resistant :-).
If the mouse is pressed and released immediately, click event should be dispatched, right? In that case, we should prevent the click event if the drop-down was active at
MOUSE_PRESSEDevent.
Makes sense.
#43 Updated by Delia Mitric 8 months ago
It's a little hard to understand how 4GL treats mouse events and CHOOSE event for a button.
1. Testcase:
DEFINE BUTTON btn.
DEFINE FRAME f
btn AT ROW 2 COL 2
WITH 1 DOWN SIZE 30 BY 10.
ENABLE ALL WITH FRAME f.
ON LEFT-MOUSE-CLICK OF BTN DO:
MESSAGE "CLICK" NOW.
END.
ON CHOOSE OF BTN DO:
MESSAGE "CHOOSE".
END.
WAIT-FOR CLOSE OF CURRENT-WINDOW.
- press the button, held an release the mouse while the cursor is on the button -> CLICK is triggered
- press the button, held an release the mouse while the cursor is outside the button -> CLICK trigger is reached.
(For this testcase, CHOOSE probably isn't reached because LEFT-MOUSE-CLICK is a low-level trigger and its definition is changed. Defining low-level triggers leads to changes which are a little confusing..)
2.Now, please remove the LEFT-MOUSE-CLICK trigger from the testcase.
- press the button, held the mouse and release it while the cursor is on the button ->
CHOOSEis triggered. - press the button, held the mouse and release it outside the button -> no
CHOOSEevent is triggered.
I'm still not sure if CHOOSE is coming from CLICK or from MOUSE-UP, but what's clear: CHOOSE is triggered just when the cursor remains on the button (even there is a long hold or not) and CLICK is dispatched for every pair of MOUSE-DOWN and MOUSE-UP (even there is a long hold or not).
In FWD, CHOOSE is coming from MOUSE_CLICKED event. MOUSE_CLICKED event is triggered after the pair MOUSE_PRESSED + MOUSE_RELEASED (if cursor remains on the button).
If MOUSE_RELEASED is realized while the cursor is outside the button, no MOUSE_CLICKED event is dispatched, so no CHOOSE event is triggered. This behavior seems to be pretty much the same as the OE behavior..
P.S. If I missed something please feel free to correct me.
#44 Updated by Hynek Cihlar 8 months ago
The mouse behavior is really weird. For example the mouse click. On most (if not all) the sane UIs click event is only triggered for short mouse down/up intervals. Another weirdness is how the mouse event triggers pevent execution of others like choose.
Or consider the following test case. When you keep clicking the button from some point of frequency sometimes you see choose trigger execute.
DEFINE BUTTON btn.
DEFINE FRAME f
btn AT ROW 2 COL 2
WITH 1 DOWN SIZE 30 BY 10.
ENABLE ALL WITH FRAME f.
ON MOUSE-SELECT-DOWN OF BTN DO:
MESSAGE "DOWN" NOW.
END.
ON CHOOSE OF BTN DO:
MESSAGE "CHOOSE".
END.
WAIT-FOR CLOSE OF CURRENT-WINDOW.
Anyway, I suggest we don't extend the scope. Let's focus on the core issue while not introducing regressions.
#46 Updated by Hynek Cihlar 8 months ago
- Status changed from Review to Internal Test
Code review 10760a. The changes look good, please go ahead with regression testing.
#47 Updated by Delia Mitric 8 months ago
- while a combo-box is active, if we try to select another radio-set item than the current one, it is selected (because of
MOUSE_RELEASEDevent). I think we have to block alsoMOUSE_RELEASEDforRADIO-SETwidget if a combo-box was active atMOUSE_PRESSED.
This happens just on the web app.
#49 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
During testing the web application, I've found another case which should be treated:
- while a combo-box is active, if we try to select another radio-set item than the current one, it is selected (because of
MOUSE_RELEASEDevent). I think we have to block alsoMOUSE_RELEASEDforRADIO-SETwidget if a combo-box was active atMOUSE_PRESSED.
This happens just on the web app.
Shouldn't we block any interaction with the rest of the UI when the drop down is active? Or are there cases where clicking actually interacts with the target widget?
#50 Updated by Delia Mitric 8 months ago
- File focus_browse.webm added
- if we try to click on a browse widget while a combo-box is active,the focus is changed to the browse.
With trunk, there are more actions made (i.e. ENTRY trigger), but with 10760a branch just the focus is changed.
#51 Updated by Delia Mitric 8 months ago
Hynek Cihlar wrote:
Delia Mitric wrote:
During testing the web application, I've found another case which should be treated:
- while a combo-box is active, if we try to select another radio-set item than the current one, it is selected (because of
MOUSE_RELEASEDevent). I think we have to block alsoMOUSE_RELEASEDforRADIO-SETwidget if a combo-box was active atMOUSE_PRESSED.
This happens just on the web app.Shouldn't we block any interaction with the rest of the UI when the drop down is active? Or are there cases where clicking actually interacts with the target widget?
I didn't found any case where clicking interacts with the target widget while the drop-down is displayed; the interaction with the rest of the UI can be made through mouse events, right? At least, just the mouse events provoke side-effect at the moment in FWD while a drop-down is active. If we block these events isn't enough?
#52 Updated by Hynek Cihlar 8 months ago
Delia Mitric wrote:
I didn't found any case where clicking interacts with the target widget while the drop-down is displayed; the interaction with the rest of the UI can be made through mouse events, right? At least, just the mouse events provoke side-effect at the moment in FWD while a drop-down is active. If we block these events isn't enough?
My point is whether we should just block the mouse events globally instead of checking the target widget.
#53 Updated by Delia Mitric 8 months ago
- Status changed from WIP to Review
- % Done changed from 90 to 100
I've committed the new changes to 10760a rev. 16282
I've changed the logic from ThinClient.processProgressEvent method to prevent MOUSE_PRESSED, MOUSE_RELEASED and MOUSE_CLICKED if a drop-down was active at MOUSE_PRESSED and to treat them if the mouse source is the active COMBO-BOX.
Hynek, please review. Thank you!
#54 Updated by Hynek Cihlar 8 months ago
- Status changed from Review to Internal Test
Code review 10760a. The changes look good. Please go ahead with regression testing.
#56 Updated by Hynek Cihlar 8 months ago
Delia, please note the javadoc for updateHeaders contains unexpected word "process".
#58 Updated by Razvan-Nicolae Chichirau 8 months ago
ChUI regression tests passed with 10760a.
#60 Updated by Radu Apetrii 8 months ago
- Status changed from Internal Test to Merge Pending
10760a can be merged right now.