Gtk: отправить фокус на окно верхнего уровня без потери первого окна верхнего уровня

Вот ситуация:

1) У меня есть два окна верхнего уровня, A и B

2) А впереди Б

Как я могу отправить фокус клавиатуры в окно B, сохраняя при этом окно A перед B?


person Tarantula    schedule 07.12.2010    source источник


Ответы (3)


Я предполагаю, что вы управляете обоими окнами, и это в системе X11, такой как Linux. Если нет, то это намного сложнее. Я делал подобные вещи в одном приложении, и вот некоторые воспоминания.

Вы, наверное, уже поняли, что не можете просто использовать gtk_widget_grab_focus(), чтобы сделать это. Это работает только для определения того, какой виджет в окне имеет фокус, когда само окно имеет фокус.

Именно X11 определяет, какое окно получает событие клавиатуры, основываясь на иерархии окон, информации от оконного менеджера и т. д. Однако вы можете поэкспериментировать с этим через GDK, чтобы получить желаемый результат.

Вам нужно будет узнать о распространении событий GDK и, возможно, прочитать некоторые источники GDK. Но я считаю, что, как правило, вам нужно сделать следующее:

  1. Используйте gdk_event_handler_set() для установки собственного обработчика событий. Вам нужно будет сделать это после инициализации GTK+ и привязать к gtk_main_do_event().
  2. Когда вы получаете событие клавиатуры (GdkEventKey), посмотрите на структуру события X. Если у него есть XID для окна A, замените его на XID для окна B и передайте его в GTK+. Возможно, вам потребуется продублировать событие, а не изменять исходное.

Если окна принадлежат разным приложениям, вы можете посмотреть gdk_event_send_client_message(), но я никогда не использовал ее.

person Bob Murphy    schedule 08.12.2010
comment
На самом деле я уже сделал шаг 1, но чего мне действительно не хватает, так это того, как я могу сравнить два GdkWindow, я не могу использовать для этого указатели. И не всегда это GdkWindow является верхним уровнем, иногда это другое окно, я даже пытался использовать g_object_set_data, чтобы добавить имя окну, но, как я уже говорил, это окно не всегда является верхним уровнем. Как я всегда могу получить верхний уровень и как я могу получить XID для GdkWindow? Большое спасибо за ваш ответ. - person Tarantula; 08.12.2010
comment
Я нашел gdk_window_get_toplevel и GDK_WINDOW_XID, посмотрю, работает ли! - person Tarantula; 08.12.2010
comment
Эй, @Tarantula, ты когда-нибудь находил решение этой проблемы? Я пытаюсь сделать то же самое, 5 лет спустя. Пожалуйста, дайте мне знать, если вы нашли трюк для этого - person TuxForLife; 23.10.2015

Если вы не возражаете, что это не напрямую, вы можете отправить события клавиатуры из окна верхнего уровня в окно за ним. Конечно, это предполагает, что оба окна созданы вами, а не написаны программа для зависания в фоновом режиме и чтения ввода с клавиатуры, используемого в отдельной программе.

person Lunin    schedule 07.12.2010

gtk_window_set_keep_above(a), за которым следует < a href="http://library.gnome.org/devel/gtk/stable/GtkWindow.html#gtk-window-present" rel="nofollow">gtk_window_present(b)?

person ptomato    schedule 09.12.2010