Compare commits

...

1 Commits

Author SHA1 Message Date
Maxim Kartashev
a618ae0581 JBR-6391 Wayland: memory indicator tooltip flickers 2023-12-06 14:32:01 +04:00
3 changed files with 57 additions and 28 deletions

View File

@@ -355,6 +355,14 @@ public final class ToolTipManager extends MouseAdapter implements MouseMotionLis
location.y);
popupFactory.setPopupType(PopupFactory.LIGHT_WEIGHT_POPUP);
if (isTooltipPositionedRelatively() && tipWindow.getComponent() != null) {
// When only relative positioning is available, we cannot know if
// the mouse is still over the "hot spot" area where tooltip needs
// to be shown. Instead, we allow the tooltip to remain visible
// as long as the mouse is over the tooltip window. To implement that,
// we want to know when the mouse enters that window.
tipWindow.getComponent().addMouseListener(this);
}
tipWindow.show();
Window componentWindow = SwingUtilities.windowForComponent(
@@ -378,6 +386,9 @@ public final class ToolTipManager extends MouseAdapter implements MouseMotionLis
window.removeMouseListener(this);
window = null;
}
if (isTooltipPositionedRelatively() && tipWindow.getComponent() != null) {
tipWindow.getComponent().removeMouseListener(this);
}
tipWindow.hide();
tipWindow = null;
tipShowing = false;
@@ -452,6 +463,11 @@ public final class ToolTipManager extends MouseAdapter implements MouseMotionLis
* @param event the event in question
*/
public void mouseEntered(MouseEvent event) {
if (isTooltipPositionedRelatively()) {
var source = event.getSource();
var tooltipComp = tipWindow != null ? tipWindow.getComponent() : null;
tooltipWindowEntered = source == tooltipComp;
}
initiateToolTip(event);
}
@@ -516,6 +532,8 @@ public final class ToolTipManager extends MouseAdapter implements MouseMotionLis
*/
public void mouseExited(MouseEvent event) {
boolean shouldHide = true;
boolean shouldHideImmediately = false;
if (insideComponent == null) {
// Drag exit
}
@@ -563,9 +581,21 @@ public final class ToolTipManager extends MouseAdapter implements MouseMotionLis
shouldHide = true;
}
}
} else if (isTooltipPositionedRelatively()) {
boolean hasExitedTooltipWindow = tipWindow != null && tipWindow.getComponent() == event.getSource();
if (hasExitedTooltipWindow) {
tooltipWindowEntered = false;
shouldHideImmediately = true;
}
}
if (shouldHide) {
if (shouldHide && !shouldHideImmediately && isTooltipPositionedRelatively()) {
// Let's wait for the tooltip window to get a chance to generate
// the "mouse enter" event. It usually doesn't take long;
// in fact, that event is probably in the queue already.
hideAttemptsCounter = 3;
SwingUtilities.invokeLater(this::maybeHideTipWindow);
} else if (shouldHide) {
enterTimer.stop();
if (insideComponent != null) {
insideComponent.removeMouseMotionListener(this);
@@ -578,6 +608,19 @@ public final class ToolTipManager extends MouseAdapter implements MouseMotionLis
}
}
private int hideAttemptsCounter = 0;
private boolean tooltipWindowEntered = false;
private void maybeHideTipWindow() {
if (tooltipWindowEntered) {
// Don't hide as the mouse is within the tooltip bounds
hideAttemptsCounter = 0;
} else if (hideAttemptsCounter-- > 0) {
SwingUtilities.invokeLater(this::maybeHideTipWindow);
} else {
hideTipWindow();
}
}
// implements java.awt.event.MouseListener
/**
* Called when the mouse is pressed.

View File

@@ -269,10 +269,9 @@ public class WLComponentPeer implements ComponentPeer {
popupLog.fine("\toffset from anchor: " + offsetFromParent);
}
nativeCreateWLPopup(nativePtr,
getParentNativePtr(target), parentX, parentY, parentWidth, parentHeight,
nativeCreateWLPopup(nativePtr, getParentNativePtr(target),
thisWidth, thisHeight,
offsetX, offsetY);
parentX + offsetX, parentY + offsetY);
} else {
nativeCreateWLSurface(nativePtr,
getParentNativePtr(target),
@@ -456,8 +455,6 @@ public class WLComponentPeer implements ComponentPeer {
performLocked(() -> {
Window popup = (Window) target;
final Component popupParent = AWTAccessor.getWindowAccessor().getPopupParent(popup);
final int parentWidth = popupParent.getWidth();
final int parentHeight = popupParent.getHeight();
final Window toplevel = getToplevelFor(popupParent);
// We need to provide popup "parent" location relative to
// the surface it is painted upon:
@@ -473,9 +470,7 @@ public class WLComponentPeer implements ComponentPeer {
popupLog.fine("\toffset of anchor from toplevel: " + toplevelLocation);
popupLog.fine("\toffset from anchor: " + newX + ", " + newY);
}
nativeRepositionWLPopup(nativePtr, parentX, parentY, parentWidth, parentHeight,
thisWidth, thisHeight,
newX, newY);
nativeRepositionWLPopup(nativePtr, thisWidth, thisHeight, parentX + newX, parentY + newY);
} );
}
@@ -940,14 +935,10 @@ public class WLComponentPeer implements ComponentPeer {
String title, String appID);
protected native void nativeCreateWLPopup(long ptr, long parentPtr,
int parentX, int parentY,
int parentWidth, int parentHeight,
int width, int height,
int offsetX, int offsetY);
protected native void nativeRepositionWLPopup(long ptr,
int parentX, int parentY,
int parentWidth, int parentHeight,
int width, int height,
int offsetX, int offsetY);
protected native void nativeHideFrame(long ptr);

View File

@@ -482,8 +482,7 @@ Java_sun_awt_wl_WLComponentPeer_nativeCreateWLSurface
static struct xdg_positioner *
newPositioner
(jint parentX, jint parentY, jint parentWidth, jint parentHeight,
jint width, jint height, jint offsetX, jint offsetY)
(jint width, jint height, jint offsetX, jint offsetY)
{
struct xdg_positioner *xdg_positioner = xdg_wm_base_create_positioner(xdg_wm_base);
CHECK_NULL_RETURN(xdg_positioner, NULL);
@@ -492,20 +491,20 @@ newPositioner
// a non-zero size set by set_size, and a non-zero anchor rectangle
// set by set_anchor_rect."
xdg_positioner_set_size(xdg_positioner, width, height);
xdg_positioner_set_anchor_rect(xdg_positioner, parentX, parentY, parentWidth, parentHeight);
xdg_positioner_set_offset(xdg_positioner, offsetX, offsetY);
xdg_positioner_set_anchor(xdg_positioner, XDG_POSITIONER_ANCHOR_TOP_LEFT);
xdg_positioner_set_anchor_rect(xdg_positioner, offsetX, offsetY, 1, 1);
xdg_positioner_set_offset(xdg_positioner, 0, 0);
xdg_positioner_set_anchor(xdg_positioner, XDG_POSITIONER_ANCHOR_BOTTOM_LEFT);
xdg_positioner_set_gravity(xdg_positioner, XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT);
xdg_positioner_set_constraint_adjustment(xdg_positioner, XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X |
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y);
xdg_positioner_set_constraint_adjustment(xdg_positioner,
XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y
| XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X
| XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y);
return xdg_positioner;
}
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLComponentPeer_nativeCreateWLPopup
(JNIEnv *env, jobject obj, jlong ptr, jlong parentPtr,
jint parentX, jint parentY,
jint parentWidth, jint parentHeight,
jint width, jint height,
jint offsetX, jint offsetY)
{
@@ -522,8 +521,7 @@ Java_sun_awt_wl_WLComponentPeer_nativeCreateWLPopup
frame->toplevel = JNI_FALSE;
assert(parentFrame);
struct xdg_positioner *xdg_positioner = newPositioner(parentX, parentY, parentWidth, parentHeight,
width, height, offsetX, offsetY);
struct xdg_positioner *xdg_positioner = newPositioner(width, height, offsetX, offsetY);
CHECK_NULL(xdg_positioner);
frame->xdg_popup = xdg_surface_get_popup(frame->xdg_surface, parentFrame->xdg_surface, xdg_positioner);
CHECK_NULL(frame->xdg_popup);
@@ -540,8 +538,6 @@ Java_sun_awt_wl_WLComponentPeer_nativeCreateWLPopup
JNIEXPORT void JNICALL
Java_sun_awt_wl_WLComponentPeer_nativeRepositionWLPopup
(JNIEnv *env, jobject obj, jlong ptr,
jint parentX, jint parentY,
jint parentWidth, jint parentHeight,
jint width, jint height,
jint offsetX, jint offsetY)
{
@@ -549,8 +545,7 @@ Java_sun_awt_wl_WLComponentPeer_nativeRepositionWLPopup
assert (!frame->toplevel);
if (wl_proxy_get_version((struct wl_proxy *)xdg_wm_base) >= 3) {
struct xdg_positioner *xdg_positioner = newPositioner(parentX, parentY, parentWidth, parentHeight,
width, height, offsetX, offsetY);
struct xdg_positioner *xdg_positioner = newPositioner(width, height, offsetX, offsetY);
CHECK_NULL(xdg_positioner);
static int token = 42; // This will be received by xdg_popup_repositioned(); unused for now.
xdg_popup_reposition(frame->xdg_popup, xdg_positioner, token++);