2017-04-25 27 views
1

XCB를 사용하여 활성 창 (입력 포커스가있는 창)을 얻는 적절한 방법은 무엇입니까?XCB를 사용하여 활성 창의 프레임 가져 오기

reply = xcb_get_input_focus_reply(connection, xcb_get_input_focus(connection), nullptr); 
std::cout << "WId: " << reply->focus; 

이것은 때로는 때로는 효과가없는 것으로 보입니다.

또한 누군가가 _NET_ACTIVE_WINDOW 루트 창 속성을 쿼리하는 것에 대해 언급했지만 어떻게 완료되었는지 그리고 항상 XCB에서 지원되는지 알 수 없습니다.

편집 : xcb_get_input_focus 만 한 부분이접근 방법과 위의 reply-> 초점을 얻기 후에, 당신은 xcb_query_tree를 통해 부모 창을 따라야합니다.

답변

2

이 솔루션은 저에게 효과적입니다. 일부 X11 코드에서 XCB로 다소 마이그레이션됩니다. 기본적으로 포커스 창을 가져 와서 창 ID가 부모 또는 루트 ID와 같을 때까지 상위 창 경로를 따라 가면 최상위 창입니다.

WId ImageGrabber::getActiveWindow() 
{ 
    xcb_connection_t* connection = QX11Info::connection(); 
    xcb_get_input_focus_reply_t* focusReply; 
    xcb_query_tree_cookie_t treeCookie; 
    xcb_query_tree_reply_t* treeReply; 

    focusReply = xcb_get_input_focus_reply(connection, xcb_get_input_focus(connection), nullptr); 
    xcb_window_t window = focusReply->focus; 
    while (1) { 
     treeCookie = xcb_query_tree(connection, window); 
     treeReply = xcb_query_tree_reply(connection, treeCookie, nullptr); 
     if (!treeReply) { 
      window = 0; 
      break; 
     } 
     if (window == treeReply->root || treeReply->parent == treeReply->root) { 
      break; 
     } else { 
      window = treeReply->parent; 
     } 
     free(treeReply); 
    } 
    free(treeReply); 
    return window; 
} 
+0

이 코드는 버그입니다. 이 모든 작업을 위해 서버를 잡아야합니다. 그렇지 않으면 트리를 통과하는 동안 입력 포커스가 변경 될 수 있습니다. XGrabServer/xcb_grab_server를 참조하십시오. –

+0

참고로 [입력] (https://github.com/i3/i3/blob/next/i3-input/main.c#L320)에서 서버가 입력 포커스 작업을 수행하는 곳을 볼 수 있습니다. –

+0

실제로 이것을 지적 해 주셔서 감사합니다. 기본적으로 처음에는 서버를'xcb_grab_server (conn)'해야하고, 끝났을 때'xcb_ungrab_server (conn)'를 써야하고 부모를 찾았습니까? –

2

내가 아는 한, EWMH 호환 윈도우 관리자는 루트 윈도우의 속성을 현재 활성화 된 윈도우의 윈도우 ID로 설정해야합니다. 그것을 얻기 위하여

,

  1. 사용 xcb_intern_atom 루트 창 ID를 가져옵니다 _NET_ACTIVE_WINDOW
  2. 의 원자 값을 얻으려면, 예를 들어, xcb_setup_roots_iterator(xcb_get_setup(connection)).data->root
  3. 사용 루트 창의 특성 값을 얻으려면 xcb_get_property, xcb_get_property_replyxcb_get_property_value을 사용하십시오.

_NET_ACTIVE_WINDOW는 XCB 목적으로, 32 비트의 크기를 가지며, CARDINAL의 유형을 갖는다.

또는이 작업을 xcb_ewmh_get_active_window 함수로 래핑하는 libxcb-ewmh을 사용할 수 있습니다.

+0

아마도이 솔루션에 대한 예를 제공 할 수 있습니까? 나는 그것을 구현할 수 없었다. 내가 이해하는 한,'xcb_intern_atom'을 사용하여'_NET_ACTIVE_WINDOW' 원자 상태를 확인할 수 있지만 어떤 창에서 사용해야합니까? –

+0

완전성을 위해'xcb_intern_atom'은 주어진 네임드 아톰의'xcb_atom_t' 값만을 반환합니다.''_NET_ACTIVE_WINDOW ''와''strlen ("_ NET_ACTIVE_WINDOW")')를 전달해야합니다. 루트 창을 가져오고 결과 아톰을 가져올 속성으로 만들고 'XCB_ATOM_CARDINAL'을 유형으로'xcb_get_property'로 가져 와서'xcb_get_property_cookie_t'를 얻습니다. 쿠키를'xcb_get_property_reply'에 건네 주면'xcb_get_property_reply_t *'를 얻을 수 있습니다. WID는'* (uint32_t *) xcb_get_property_value (...)'가 될 것입니다; 회신을 해방하는 것을 잊지 마십시오. – aitap

+0

EWMH에 의존하는 대다수의 경우 올바른 방법과 원하는 것입니다. 그러나 EWMH 힌트는 현재 입력 포커스가있는 윈도우를 참조 할 필요는 없으므로 실제로는 @dporobic이 실제로 수행하고자하는 작업에 대한 질문입니다. –