LINUX.ORG.RU

Ответ на: комментарий от arrecck

Ну вот например иерархия xwininfo https://ibb.co/2ZNp5P1 Подписываюсь на события для parent window. При нажатии менюшек типо «файл», «правка» появляются контекстные окошки, а соответствующих ивентов не приходит(не map не create).

ZombieCommander ()
Ответ на: комментарий от arrecck

я решил проверить. В гугле говорят, что fly написан на qt5. Ok, простая менюшка.

#include <QApplication>
#include <QMainWindow>
#include <QMenu>
#include <QMenuBar>
#include <QDebug>

int main(int argc, char *argv[]) {

  QApplication app(argc, argv);
 
  QMainWindow *w = new QMainWindow;
  QMenu* file = w->menuBar()->addMenu("File");
  QMenu* edit = w->menuBar()->addMenu("Edit");
  file->addMenu("Create");
  file->addMenu("Quit");
  edit->addMenu("Copy");
  edit->addMenu("Paste");
  qDebug() << w->winId();
  qDebug() << file->winId();
  qDebug() << edit->winId();
  w->show();
  return app.exec();

}

результат

35651590
35651594
35651597

И у mainwindow, и у меню родитель рутовое окно(проверяется через xprop)
Меню с типом
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DROPDOWN_MENU, _NET_WM_WINDOW_TYPE_POPUP_MENU, _NET_WM_WINDOW_TYPE_NORMAL.
Далее пишем наш клиент.
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb.h>

int main() {
    xcb_connection_t *conn = xcb_connect (NULL, NULL);
    xcb_screen_t *screen = xcb_setup_roots_iterator (xcb_get_setup (conn)).data;

    uint32_t mask = XCB_CW_EVENT_MASK;
    uint32_t values[1] = {XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY};
    xcb_change_window_attributes(conn, screen->root,mask, values);
    xcb_flush(conn);
    xcb_generic_event_t *event;
    while ((event = xcb_wait_for_event (conn))) {
        switch (event->response_type & ~0x80) {
        case XCB_CREATE_NOTIFY:{
            xcb_create_notify_event_t *ev = (xcb_create_notify_event_t *)event;
            printf("create win %d\n",ev->window);
            break;} 
        case XCB_MAP_NOTIFY:{
            xcb_map_notify_event_t *ev = (xcb_map_notify_event_t *)event;
            printf("map win %d\n",ev->window);
            break;
        }
        case XCB_UNMAP_NOTIFY:{
            xcb_unmap_notify_event_t *ev = (xcb_unmap_notify_event_t *)event;
            printf("unmap win %d\n",ev->window);
            break;
        }
        }
        free(event);

    }
    return 0;
}

результат
create win 35651588
create win 35651590-> это MainWindow
create win 35651592
create win 35651594->Меню File
create win 35651597->Меню Edit
map win 35651590 -> после запуска

map win 35651594 ->при нажатии на меню
unmap win 35651594
unmap win 35651594
map win 35651597
unmap win 35651597
unmap win 35651597

qt создает какие-то дополнительные окна, это уже надо в кишки смотреть. Если в fly-terminal не так, то надо смотреть исходники fly.

arrecck ★★ ()
Ответ на: комментарий от ZombieCommander

я подписался на родителя окон меню. Qt их делает дочерними к рутовому окну, а не к окну приложения(QMainWindow). Как обычно для qt можно задать parent widget через конструктор.
QMenu(const QString &title, QWidget *parent = nullptr)
Надо смотреть исходники класса QMenu и исходники того приложения, события которого ты хочешь получить.

arrecck ★★ ()
Ответ на: комментарий от arrecck

Спасибо. Я к хочу получить события от любого, выбранного пользователем приложения. Есть ли какой-нибудь способ узнать, что вызванное окно принадлежит именно моему окну(приложению)?

ZombieCommander ()
Ответ на: комментарий от ZombieCommander

я бы создал список с нужными id, затем при получении события от окна сверял бы через xcb_query_tree или xcb_query_tree_children.
Еще все можно раскрутить в обратном порядке. Для многих событий в структуре есть поле parent, это родительское окно. Через него можно получить цепочку parent->parent и т.д.

arrecck ★★ ()
Ответ на: комментарий от arrecck

К сожалению не понял, что вы написали. Всё равно parent у всех будет root окно, смысл проверять дерево? Кажется нашёл что qt ставит в wm_hints id процесса, и похоже они совпадают с id процесса приложения, попробую так.

ZombieCommander ()