Community
Participate
Working Groups
Please found below source code to reproduce problem. This is a tiny shell displaying two rectangle a red and a blue on a gray background. a MouseMoveListener is used to check on which area of shell the mouse is, if mouse is over red rectangle the "Red Rectangle" tooltip is displayed, the "Blue tooltip" is displayed if mouse is over blue rectangle. Otherwise tooltip is reseted (hidden) using setToolTipText(null) call. When mouse enter shell on red area tooltip is displayed (on the bottom of shell but displayed), if mouse go from red to blue then come back to red are (without flying gray area) both Red and Blue tooltip text are displayed correcly. If mouse flies over gray area tooltip disappear due to setToolTipText(null) call, But if mouse goes to red or blue area none of expected tooltip are shown until mouse go out of shell and come back on a red/blue area (and only if last setToolTipText() call before going outside shell wasn't a (null) call.). In addition I'm very disappointed by the location of the tooltip: always at the bottom of the control which want to display it, in this little sample, tooltip is displayed below shell. I've tried using Eclipse 3.0.2 (IES build 200501191352) on a Suse Linux 8.2, window manager is QLWM. Source code to reproduce: package tooltip; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; /** * This code reproduce GTK's setToolTipText(null) problem. */ public class TestTooltip { public static void main(String[]v) { Display disp = Display.getDefault(); final Shell shell = new Shell(disp, SWT.DIALOG_TRIM|SWT.RESIZE ); shell.setText( "Test Tooltip" ); shell.setLayout( new FillLayout() ); final Canvas canvas = new Canvas( shell, SWT.NONE ); canvas.addPaintListener( new PaintListener() { public void paintControl(PaintEvent e) { Rectangle r = canvas.getClientArea(); int wm = r.width/8, w2 = r.width/2; int hm = r.height/8, h2 = r.height/2; int rw = w2-wm, rh = r.height-2*hm; e.gc.setBackground( new Color(null,200,0,0) ); e.gc.fillRectangle( 0,hm,w2,rh); e.gc.setBackground( new Color(null,0,0,200) ); e.gc.fillRectangle( w2,hm+hm,rw+wm,rh-hm); } }); canvas.addMouseMoveListener( new MouseMoveListener() { public void mouseMove(org.eclipse.swt.events.MouseEvent e) { int mx = e.x; int my = e.y; Rectangle r = canvas.getClientArea(); int wm = r.width/8, w2 = r.width/2; int hm = r.height/8, h2 = r.height/2; int rw = w2-wm, rh = r.height-2*hm; String tip = null; if( mx>=0 && mx <= 0+w2 && my >= hm && my <= hm+rh ) { tip = "Red Rectangle"; } else if( mx>=w2 && mx <= w2+rw+wm && my >= hm+hm && my <= hm+rh ) { tip = "Blue Rectangle"; } System.out.println("setToolTipText("+tip+")"); canvas.setToolTipText( tip ); } }); shell.setSize( 300, 200 ); shell.open(); while (!shell.isDisposed()) if (!disp.readAndDispatch()) disp.sleep(); } }
There are two bugs here. The first is actually that calling setToolTipText() while the cursor is inside of the Canvas causes unexpected things to happen. The second problem is that the tooltip appears outside of the Canvas, so I opened a new bug for that (bug 85328). Below is a smaller example which shows the problem. What is happening here is that GTK+ tooltips are displayed and hidden based on enter and leave events for the entire widget. If you set the tooltip text while the mouse cursor is inside the widget, it will not appear until the mouse leaves and re-enters the widget. However, if there is already a tooltip visible and you change the text, the change appears immediately. The real issue is that GTK+ tooltips aren't designed to be manipulated like this from a mouse listener. There are many bugs about tooltips in the GTK+ bugtracker, this one probably being the most relevant: http://bugzilla.gnome.org/show_bug.cgi?id=62174 I am not sure if it is possible to work around these limitations. An option in the short term would be to create your own tooltip shells so that you can control their position and behaviour manually. public static void main(String [] args) { final Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); final Canvas canvas = new Canvas(shell, SWT.NONE); final Rectangle tooltipArea = new Rectangle(0,40,200,40); canvas.addMouseMoveListener(new MouseMoveListener() { public void mouseMove(MouseEvent e) { if(tooltipArea.contains(e.x, e.y)) { if(canvas.getToolTipText() == null) { canvas.setToolTipText("This is a tooltip"); } } else { if(canvas.getToolTipText() != null) { canvas.setToolTipText(null); } } } }); canvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { e.gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE)); e.gc.fillRectangle(tooltipArea); } }); shell.open(); while(!shell.isDisposed()) { if(!display.readAndDispatch()) display.sleep(); } display.dispose(); }
I know that I can do tooltip myself rewritting source code, I made a little investigation around me on guys working with tooltips, all of them having tooltip without bug ... write their own tooltip, never trusting SWT ones ! In my point of view, this is a same to have to write our own tooltip if we want them working good on all platform SWT officially support ! I mean, as SWT Control class propose setToolTipText() method, Control class have the obligation to have working tooltip on all platform SWT is ported on. If the solution is "write yourself your tooltip using Shell", the right answer must be SWT Control class (for GTK and other) must use a shell to show tooltip ! Why ? because doing this all swt user will have the benefit of working tooltip on all platform without rewritting and copying any source code, in this way SWT will behave as a real portable UI toolkit library.
I can't reproduce this bug, marking as closed. Please re-open if the issue persists.