С++ GTK 3: получить фокус клавиатуры на окно

Я пытаюсь закрыть окно GTK, нажав + q в Mac OS или ALT + F4 в Windows .

Приведенный ниже код отлично работает, если я нажму на окно один раз. Если я не нажму, все команды будут переданы в базовый терминал. Так, например. если я нажму + q, мой терминал спросит меня, хочу ли я закрыть его (терминал). Но как только я нажимаю на окно с помощью указателя мыши, я могу использовать + q, чтобы закрыть это окно. Странно, что окна не получают фокуса при запуске, поскольку я чувствую, что все мои обычные приложения получают фокус для ввода с клавиатуры при запуске.

main.cpp

// Copyright 2017 Sebastian Höffner

#include "gtk/gtk.h"


namespace {

static void cb_key_press(GtkWidget* widget, GdkEventKey* event_key) {
  switch (event_key->keyval) {
    case GDK_KEY_F4:
      if (event_key->state & GDK_MOD1_MASK) {
        gtk_main_quit();
      }
      break;
    case GDK_KEY_q: case GDK_KEY_W:
      if (event_key->state & GDK_META_MASK) {
        gtk_main_quit();
      }
      break;
  }
}

}  // namespace

int main(int argc, char** argv) {
  gtk_init(&argc, &argv);

  GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  g_signal_connect(window, "key-press-event", G_CALLBACK(::cb_key_press), NULL);
  g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

  gtk_window_fullscreen(GTK_WINDOW(window));
  gtk_window_present(GTK_WINDOW(window));

  gtk_main();

  return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

# Project options
project(gtk_test VERSION 0.1 LANGUAGES CXX C)

find_package(PkgConfig)
pkg_check_modules(GTK gtk+-3.0)

include_directories(${GTK_INCLUDE_DIRS})
link_directories(${GTK_LIBRARY_DIRS})
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_link_libraries(${PROJECT_NAME} ${GTK_LIBRARIES})

Для компиляции поместите оба файла (CMakeLists.txt и main.cpp) в один и тот же каталог и выполните следующие команды:

mkdir build
cd build
cmake ..
make

Затем вы можете запустить программу ./gtk_test (она находится в build).

Еще немного истории

Сначала я изменил пример начала работы, но быстро обнаружил, что использование GtkApplication кажется излишним для моего приложения (которое в основном должно отображать только полноэкранные изображения, поэтому highgui OpenCV недостаточно хорош без бэкэнда Qt), поэтому я адаптировал gtk_window_new(GTK_WINDOW_TOPLEVEL);, который я нашел в различных ответах и ​​учебниках.

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

ОБНОВЛЕНИЕ: добавлен файл CMakeLists.txt и удалены сгенерированные сообщения компиляции. Добавлены пояснения о том, как компилировать и запускать.


person Sebastian Höffner    schedule 14.09.2017    source источник
comment
Попробуйте некоторые из ответов здесь и дайте мне знать, как это работает.   -  person theGtknerd    schedule 14.09.2017
comment
Я пробовал gtk_window_set_keep_above(GTK_WINDOW(window), true); раньше, я наткнулся на тот же вопрос. Я только что попробовал еще раз, но это не то, что я хочу. Я предполагаю, что он позаботится о том, чтобы окно оставалось самым верхним, что в любом случае происходит в полноэкранных окнах в MacOS. Я хочу, чтобы фокус клавиатуры был перенесен с вызывающего терминала в новое окно.   -  person Sebastian Höffner    schedule 15.09.2017
comment
Вы также пробовали gtk_window_present() ?   -  person theGtknerd    schedule 15.09.2017
comment
Да, это часть кода выше.   -  person Sebastian Höffner    schedule 15.09.2017
comment
Виноват. Я вижу, что у вас нет gtk_widget_show_all() для главного окна.   -  person theGtknerd    schedule 15.09.2017
comment
У меня его нет в этом простом примере, потому что это сделает видимыми только все виджеты, содержащиеся в окне, в более сложном примере я использую его. Но я также попробовал это для этого примера сейчас, к сожалению, он все еще не работает должным образом.   -  person Sebastian Höffner    schedule 16.09.2017
comment
Раньше был gtk_window_raise() или что-то в этом роде, но я не могу найти ссылку на него. К сожалению, кажется, у меня заканчиваются предложения.   -  person theGtknerd    schedule 16.09.2017
comment
Спасибо, что все еще пытаетесь помочь, это очень ценится!   -  person Sebastian Höffner    schedule 16.09.2017
comment
Еще одно предложение: возможно, это фокус< /а> проблема.   -  person theGtknerd    schedule 16.09.2017
comment
Я пытался, безуспешно. Возможно, это связано с тем, что по умолчанию уже используется true. Моя ставка в настоящее время составляет has-toplevel-focus, но это свойство только для чтения. Возможно, я смогу установить его через GtkBuilder с файлом ui xml. Еще раз спасибо за ваш вклад.   -  person Sebastian Höffner    schedule 16.09.2017
comment
Остается доступным только для чтения, даже с GtkBuilder и файлом пользовательского интерфейса.   -  person Sebastian Höffner    schedule 19.09.2017
comment
Как вы компилируете этот пример? Я использую Linux и Python, поэтому мне нужна помощь, чтобы попытаться воспроизвести вашу проблему.   -  person theGtknerd    schedule 20.09.2017
comment
Я обновил пример, чтобы предоставить CMakeLists.txt и инструкции по сборке.   -  person Sebastian Höffner    schedule 21.09.2017
comment
У меня в линуксе нормально работает. Как насчет другого фокуса .   -  person theGtknerd    schedule 22.09.2017
comment
Я пробовал, без изменений. Согласно glade, в любом случае это значение по умолчанию. Но тогда я думаю, что это проблема ОС. Скоро попробую и на машине с linux.   -  person Sebastian Höffner    schedule 22.09.2017