blob: 558ee6983960b683b7422e935b6a770970055cb7 [file] [log] [blame]
package org.eclipse.swt.tests.gtk.snippets;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.gtk.GtkAllocation;
import org.eclipse.swt.internal.gtk.OS;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;
/*
* Title: Bug 526083 - [GTK3] Menu.getBounds() returns wrong x & y coordinate
* How to run: launch snippet, right click in the boxes, observe messages printed in the console
* Bug description: The "getBounds" line has incorrect values
* Expected results: The "getBounds" line should have the same values as the "correct bounds" line
* GTK Version(s): GTK3
*/
@SuppressWarnings("restriction")
public class Bug526083_MenuGetBounds {
public static void main(String[] args) {
final Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout(2, false));
Composite c1 = new Composite(shell, SWT.BORDER);
c1.setLayoutData(new GridData(100, 100));
Composite c2 = new Composite(shell, SWT.BORDER);
c2.setLayoutData(new GridData(100, 100));
final Menu menu = new Menu(shell, SWT.POP_UP);
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("Popup");
menu.addListener(SWT.Show, event -> display.asyncExec(() -> {
try {
// menu.getBounds call
System.err.println("getBounds: " + invoke(menu, "getBounds"));
System.err.println("-----------------------------------------");
// menu.getBounds implementation
// long /*int*/ window = gtk_widget_get_window (menu.handle);
long /*int*/ window = ((Long)invoke(Widget.class, "gtk_widget_get_window", true, menu, new Object[] { Long.valueOf(menu.handle) })).longValue();
int [] origin_x = new int [1], origin_y = new int [1];
OS.gdk_window_get_origin (window, origin_x, origin_y);
GtkAllocation allocation = new GtkAllocation ();
OS.gtk_widget_get_allocation (menu.handle, allocation);
System.err.println(origin_x[0] + " " + origin_y[0] + " " + allocation.x + " " + allocation.y + " " + allocation.width + " " + allocation.height);
int x = origin_x [0] + allocation.x;
int y = origin_y [0] + allocation.y;
int width = allocation.width;
int height = allocation.height;
Rectangle bounds = new Rectangle (x, y, width, height);
System.err.println("allocation: " + allocation.x + " " + allocation.y + " " + allocation.width + " " + allocation.height);
System.err.println("bounds: " + bounds);
System.err.println("-----------------------------------------");
// correct bounds (without allocation)
x = origin_x [0];
y = origin_y [0];
bounds = new Rectangle (x, y, width, height);
System.err.println("correct bounds: " + bounds);
} catch (Throwable t) {
t.printStackTrace();
}
}));
c1.setMenu(menu);
c2.setMenu(menu);
shell.setMenu(menu);
shell.setSize(300, 300);
shell.setLocation(100, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
public final static Object invoke(final String clazzName, final String methodName, final Object... args)
throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
return invoke(clazzName, methodName, false, args);
}
public final static Object invoke(final String clazzName, final String methodName, final Class<?>[] params, final Object... args)
throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
return invoke(Class.forName(clazzName), methodName, false, null, params, args);
}
public final static Object invoke(final String clazzName, final String methodName, final boolean declaredMethod, final Object... args)
throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
return invoke(Class.forName(clazzName), methodName, declaredMethod, null, args);
}
public final static Object invoke(final Object obj, final String methodName, final Object... args)
throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
return invoke(obj.getClass(), methodName, true, obj, args);
}
public final static Object invoke(final Class<?> clazz, final String methodName, final boolean declaredMethod, final Object obj, final Object... args)
throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Class<?>[] params = new Class[args.length];
for (int i = 0; i < args.length; i++) {
Class<?> argClazz = args[i].getClass();
try {
Field typeField = argClazz.getField("TYPE"); //$NON-NLS-1$
params[i] = (Class<?>) typeField.get(null);
} catch (NoSuchFieldException e) {
params[i] = argClazz;
}
}
return invoke(clazz, methodName, declaredMethod, obj, params, args);
}
public final static Object invoke(final Class<?> clazz, final String methodName, final boolean declaredMethod, final Object obj, final Class<?>[] params, final Object... args)
throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Method method;
if (declaredMethod) {
method = clazz.getDeclaredMethod(methodName, params);
method.setAccessible(true);
} else {
method = clazz.getMethod(methodName, params);
}
return method.invoke(obj, args);
}
}