Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Window ID from Java SWT

Tags:

java

swt

I would like to find the window ID of my SWT program.

I start up my SWT shell in the standard way. How do I then find the ID of the window that's been created? The program is executing on Fedora 10 using the Compiz-Fusion window manager (if that makes a difference).

Code to help explain what I mean:

public static void main(String[] args) {
  Display display = new Display();
  Shell shell = new Shell();

  // find window ID here??

  shell.open();

  while (!shell.isDisposed()) {
    if(!display.readAndDispatch()) {
      display.sleep();
    }
  }
}

Update 6 Mar 2009 After looking at and trying out a whole range of things (thanks to VonC for the suggestions below), I came across something that's worked so far. It's supremely dodgy but at least allows me to get on with some other work for the moment.

The ID returned from Control.embeddedHandle is close to the window ID. It's different by a predictable offset. So my code is:

public static void main(String[] args) {
  ...
  Shell shell = new shell(display, SWT.NONE);

  Composite e = new Composite(shell, SWT.EMBEDDED);
  long windowID = e.embeddedHandle - WINDOW_ID_MAGIC_NUMBER;
  e.dispose();
  ....

WINDOW_ID_MAGIC_NUMBER is 5+(number of widgets added to shell before the embedded composite).

It seems reliable on my system so far. I have yet to see if it falls over in a different environment.

like image 281
cursa Avatar asked Mar 04 '09 04:03

cursa


2 Answers

Not sure if this still matters to you, 7 years later :-), but this works for me:

private static long getWindowIdFromShell(Shell shell) {
  long handle = shell.handle;
  long topWidget = OS._gtk_widget_get_toplevel(handle);
  long topWindow = OS._gtk_widget_get_window(topWidget);
  long topXid = OS._gdk_x11_window_get_xid(topWindow);
  return topXid;
}

In particular, the "get_toplevel" step is what jumps to the root widget/window, and so means you don't need the "minus magic window offset" hack (which I was initially stuck doing as well).

like image 38
Stephen Haberman Avatar answered Oct 27 '22 11:10

Stephen Haberman


If you create a Composite with the style SWT.EMBEDDED style, then under SWT/GTK+ Composite.embeddedHandle will be an X window ID you can use for parenting an XEMBED child.

Composite embed = new Composite(shell, SWT.EMBEDDED);
System.out.println ("X window ID: " + embed.embeddedHandle);
int hwndChild = OS.GetWindow ( c.handle, OS.GW_CHILD);

This supports embedding using the XEMBED protocol.

This is similar to the JNI code used to get the window ID from its handle

GtkWidget *widget = (GtkWidget *) handle;
GdkWindow *window = widget->window;
xwinid = GDK_WINDOW_XWINDOW(window);

Example of code here.

Example of class using OS:

org.eclipse.swt.widgets.Tree, org.eclipse.swt.widgets.CoolItem,

OS I can find is indeed org.eclipse.swt.internal.win32.OS, not gtk, and it is not a perfect solution because you would access an internal package, but that can give you an idea where to look.

In your case, org.eclipse.swt.internal.gtk.OS is the right class, and you should look in Tree or CoolItem sources how they are using the GetWindow function.
Some other function need to be called in GTK, like may be gtk_container_get_children(int container);

It is said in an answer to the message I was referring at the beginning

If you need the X window, there's no way to do this from the public SWT API (even going through internals), and furthermore even if there was a way I don't think you could guarantee it for all controls. I'm not sure if this works but the closest you could get might be to:

  1. make Control.fixedHandle public
  2. Use OS.GTK_WIDGET_WINDOW (control.fixedHandle) to get a GdkWindow
  3. Use OS.gdk_x11_drawable_get_xid (gdkWindow) to translate that to an X window

I guess the other way might be to take Control.handle, and then call GTK_WIDGET_WINDOW() on it, or if that's null keep calling it on its parents until you find one with a GdkWindow, and then translate that to an X window.

The difficulty here is that SWT talks to GTK+, which talks to GDK, which then talks to X. So, there's three layers between you and the X window.

like image 114
VonC Avatar answered Oct 27 '22 09:10

VonC