AndrewCrewKuznetsov/xneur-devel

Описать архитектуру приложения в readme

Opened this issue · 0 comments

@AndrewCrewKuznetsov, необходимо высокоуровневое описание того, как приложение работает и почему именно так. Например, изучая код (к сожалению, он не содержит коментариев), я нашел, что на самом верхнем уровне приложение выглядит так:

  1. Регистрируются обработчики сигналов
    xneur_trap(SIGTERM, xneur_terminate);
    xneur_trap(SIGINT, xneur_terminate);
    xneur_trap(SIGHUP, xneur_reload);
    xneur_trap(SIGCHLD, xneur_zombie);
    xneur_trap(SIGTSTP, xneur_terminate);
  2. Создается невидимое окно приложения, которое будет получать события от клавиатуры и мыши
    // Create Main Window
    Window window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, 100, 100, 0, 0, 0);
    if (!window)
    {
    log_message(ERROR, _("Can't create program window"));
    XCloseDisplay(display);
    return FALSE;
    }
  3. Создается окно для отображения флага (почему этим занимается сам xneur, а не его gxneur и kxneur?)
    // Create flag window
    XSetWindowAttributes attrs;
    attrs.override_redirect = True;
    Window flag_window = XCreateWindow(display, DefaultRootWindow(display), 0, 0, 1, 1,0, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attrs);
    if (!flag_window)
    {
    log_message(ERROR, _("Can't create flag window"));
    XCloseDisplay(display);
    return FALSE;
    }
  4. Создаются обработчики событий подсистеы X Window
    p->event = event_init(); // X Event processor
  5. Создаются обработчики смены фокуса активного окна
    p->focus = focus_init(); // X Input Focus and Pointer processor
    • При смене фокуса основное окно приложения подписывается на интересующие его события сфокусированного окна и отписывается от событий ранее сфокусированного окна
      static void focus_update_grab_events(struct _focus *p, int mode)
      {
      char *owner_window_name = get_wm_class_name(p->owner_window);
      if ((mode == LISTEN_DONTGRAB_INPUT) || (p->last_focus == FOCUS_EXCLUDED))
      {
      grab_button(FALSE);
      grab_all_keys(p->owner_window, FALSE);
      }
      else
      {
      if (xconfig->tracking_mouse)
      grab_button(TRUE);
      grab_all_keys(p->owner_window, TRUE);
      }
  6. Запускается бесконечный цикл ожидания событий от X Window
    static void program_process_input(struct _program *p)
    {
    p->update(p);
    while (1)
    {
    int type = p->event->get_next_event(p->event);

Хотелось бы более подробное и официальное описание работы. Например,

  • почему сделаны постоянные подписывания/отписывания от события? Чем это лучше, если бы основное окно подписалось на все события?
  • Каким образом осуществляется само действие смены раскладки?
  • Зачем вообще создается окно приложения, почему нельзя было сразу подписать root window?
  • Зачем реализована система аля классы C++, хотя везде всего одна "реализация" (т.е. есть структура с функциями, при вызове методов structname_init туда записываются адреса функций, а далее вызываются они через указатели из структуры). Эти косвенные вызовы усложняет анализ кода, а преимуществ не видно
  • Жизненный цикл плагинов