Идентификатор окна из Java SWT - PullRequest
5 голосов
/ 04 марта 2009

Я хотел бы найти идентификатор окна моей программы SWT.

Я запускаю свою SWT-оболочку стандартным способом. Как мне найти идентификатор созданного окна? Программа выполняется в Fedora 10 с помощью оконного менеджера Compiz-Fusion (если это имеет значение).

Код, помогающий объяснить, что я имею в виду:

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();
    }
  }
}

Обновление 6 марта 2009 Посмотрев и опробовав целый ряд вещей (спасибо VonC за предложения ниже), я наткнулся на то, что до сих пор работало. Это в высшей степени хитроумно, но, по крайней мере, позволяет мне сейчас заняться какой-то другой работой.

Идентификатор, возвращаемый из Control.embeddedHandle, близок к идентификатору окна. Это отличается предсказуемым смещением. Итак, мой код:

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 - 5+ (количество виджетов, добавленных в оболочку до встроенного композита).

Пока что в моей системе это выглядит надежно. Мне еще предстоит выяснить, падает ли он в другой среде.

Ответы [ 3 ]

3 голосов
/ 17 октября 2016

Не уверен, если это все еще имеет значение для вас, 7 лет спустя :-), но это работает для меня:

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;
}

В частности, шаг «get_toplevel» - это то, что переходит к корневому виджету / окну, и, следовательно, означает, что вам не нужен хак «минус смещение магического окна» (который я изначально застрял при этом) *

3 голосов
/ 04 марта 2009

Если вы создадите Composite со стилем SWT.EMBEDDED, то в SWT / GTK + Composite.embeddedHandle будет идентификатор X-окна, который вы можете использовать для родительского элемента дочернего элемента XEMBED.

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

Это поддерживает встраивание с использованием протокола XEMBED.

Это похоже на код JNI, используемый для получения идентификатора окна из его дескриптора

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

Пример кода здесь .

Пример класса с использованием ОС:

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

ОС, которую я могу найти, действительно org.eclipse.swt.internal.win32.OS , а не gtk, и это не идеальное решение, потому что вы получите доступ к внутренний пакет, но это может дать вам представление, где искать.

В вашем случае org.eclipse.swt.internal.gtk.OS - это правильный класс, и вы должны посмотреть в источниках Tree или CoolItem, как они используют функцию GetWindow.
В GTK должна быть вызвана какая-то другая функция, например, может быть gtk_container_get_children(int container);

В ответе сказано на сообщение, которое я имел в виду

Если вам нужно окно X, то нет способа сделать это из общедоступного API SWT (даже через внутренние компоненты), и, более того, даже если бы был способ, который я не думаю, вы могли бы гарантировать его для всех элементов управления. Я не уверен, что это работает, но самое близкое, что вы могли бы получить:

  1. сделать Control.fixedHandle общедоступным
  2. Используйте OS.GTK_WIDGET_WINDOW (control.fixedHandle), чтобы получить GdkWindow
  3. Используйте OS.gdk_x11_drawable_get_xid (gdkWindow), чтобы перевести это в окно X

Полагаю, другим способом было бы взять Control.handle, а затем позвонить на него GTK_WIDGET_WINDOW(), или, если это null, продолжать звонить его родителям, пока не найдете один с GdkWindow, а затем переведите это в окно X.

Сложность в том, что SWT общается с GTK +, который общается с GDK, который затем общается с X. Итак, между вами и окном X есть три слоя.

0 голосов
/ 12 июня 2009

Спасибо, это мне очень помогло. У меня есть встроенный холст SWT для показа видео с помощью mplayer.

Я нашел другой пример, где Canvas был создан как элемент управления SWT. Я мог видеть поле embeddedHandle при отладке, но не мог получить доступ / использовать его.

Согласно вашему примеру, я переключился с SWT Control на Composite, и теперь я могу получить доступ к embeddedHandle, и это работает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...