Skip to content

Commit a8310a6

Browse files
authored
Reduce excess positioning calls for ComboBox popup. (#11808)
- If an open popup is reset to its default position on every update from the server before getting adjusted again to the actual expected position, on heavier applications some of those intermediate positions might get rendered. If the ComboBox is positioned at the right edge and the popup contents are longer than the input field (i.e. popup should open to the left, not right) this might cause flickering. - Setting the default position is only actually needed when the popup is opened in order to give it a baseline, otherwise it's better to simply adjust the position if needed. Continues on #11718
1 parent 9d03f99 commit a8310a6

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

client/src/main/java/com/vaadin/client/ui/VComboBox.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -428,10 +428,15 @@ public void showSuggestions(final int currentPage) {
428428
// Add TT anchor point
429429
getElement().setId("VAADIN_COMBOBOX_OPTIONLIST");
430430

431-
leftPosition = getDesiredLeftPosition();
432-
topPosition = getDesiredTopPosition();
431+
// Set the default position if the popup isn't already visible,
432+
// the setPopupPositionAndShow call later on can deal with any
433+
// adjustments that might be needed
434+
if (!popup.isShowing()) {
435+
leftPosition = getDesiredLeftPosition();
436+
topPosition = getDesiredTopPosition();
433437

434-
setPopupPosition(leftPosition, topPosition);
438+
setPopupPosition(leftPosition, topPosition);
439+
}
435440

436441
int nullOffset = getNullSelectionItemShouldBeVisible() ? 1 : 0;
437442
boolean firstPage = currentPage == 0;
@@ -894,16 +899,24 @@ public void setPosition(int offsetWidth, int offsetHeight) {
894899
}
895900
}
896901

902+
if (offsetWidth + menuMarginBorderPaddingWidth
903+
+ left < VComboBox.this.getAbsoluteLeft()
904+
+ VComboBox.this.getOffsetWidth()) {
905+
// Popup doesn't reach all the way to the end of the input
906+
// field, filtering may have changed the popup width.
907+
left = VComboBox.this.getAbsoluteLeft();
908+
}
897909
if (offsetWidth + menuMarginBorderPaddingWidth + left > Window
898910
.getClientWidth()) {
911+
// Popup doesn't fit the view, needs to be opened to the left
912+
// instead.
899913
left = VComboBox.this.getAbsoluteLeft()
900914
+ VComboBox.this.getOffsetWidth() - offsetWidth
901915
- (int) menuMarginBorderPaddingWidth;
902-
if (left < 0) {
903-
left = 0;
904-
menu.setWidth(Window.getClientWidth() + "px");
905-
906-
}
916+
}
917+
if (left < 0) {
918+
left = 0;
919+
menu.setWidth(Window.getClientWidth() + "px");
907920
}
908921

909922
setPopupPosition(left, top);

0 commit comments

Comments
 (0)