2011-03-10 2 views
4

Xlib을 사용하여 활성 창이 언제 바뀌는 지 추적하는 프로그램을 작성하려고합니다. 이 작업을 수행하는 가장 좋은 방법을 찾는 데 어려움이 있습니다. 다음은 지금까지 내 생각은 다음과 같습니다xlib에 활성 창 이벤트가 있습니까?

  • 매초마다 사용 _NET_ACTIVE_WINDOW 활성 창을 얻을이 변경된 경우 다음 이벤트에 대한 관련 코드를 실행 할 수 있습니다.
  • 모든 창 목록을 가져 와서 이벤트에서 포커스를 수신합니다. 나는 열려있는 창의 최신 목록을 유지하는 방법을 알아 내야 할 것이다.

더 쉽고/더 나은 방법인가요? 나는 Xlib 프로그래밍에 익숙하지 않다.

+0

모든 포커스 이벤트를 듣고 모든 윈도우에 대해 모든 핸들러를 등록하는 것은 매우 비싼 것 같습니다. 실제로 PointerMove를 일반 사용자가 청취하고 이벤트 핸들러에서'XGetInputFocus()'를 호출하면 이동했을 때 누가 그것을 가지고 있는지를 알아내는 것이 더 적은 오버 헤드가 될지 궁금하다. 얼마나 실시간으로해야합니까? 그 대답은 "초 괜찮습니다"다음 폴링 방법이 가장 좋은 것 같습니다. –

+0

실시간으로 처리 할 필요는 없습니다. 몇 초 안에 괜찮을 것입니다. 나는 첫 번째 방법을 시도해 볼 것이다. 감사합니다 FrankH. – Jim

답변

0

저는 "활성 창 변경 이벤트 그래버"도 찾고있었습니다. 평균 시간에 사용하는 것은 xdotoolxwininfo의 조합입니다. 그냥 루트 창에서 PropertyChange를 선택할 수 없습니다

xwininfo -id "$(xdotool getactivewindow)" 
2

는 속성이 업데이트 될 때 PropertyNotify 이벤트를 전송 한 후이 _NET_ACTIVE_WINDOW 위해이었다 여부를 확인하려면 각 이벤트를 확인하세요?

1

여기 @alanc이 제안한 것의 파이썬 구현입니다.

import Xlib 
import Xlib.display 

disp = Xlib.display.Display() 
root = disp.screen().root 

NET_ACTIVE_WINDOW = disp.intern_atom('_NET_ACTIVE_WINDOW') 
NET_WM_NAME = disp.intern_atom('_NET_WM_NAME') 

last_seen = {'xid': None} 
def get_active_window(): 
    window_id = root.get_full_property(NET_ACTIVE_WINDOW, 
             Xlib.X.AnyPropertyType).value[0] 

    focus_changed = (window_id != last_seen['xid']) 
    last_seen['xid'] = window_id 

    return window_id, focus_changed 

def get_window_name(window_id): 
    try: 
     window_obj = disp.create_resource_object('window', window_id) 
     window_name = window_obj.get_full_property(NET_WM_NAME, 0).value 
    except Xlib.error.XError: 
     window_name = None 

    return window_name 


if __name__ == '__main__': 
    root.change_attributes(event_mask=Xlib.X.PropertyChangeMask) 
    while True: 
     win, changed = get_active_window() 
     if changed: 
      print(get_window_name(win)) 

     while True: 
      event = disp.next_event() 
      if (event.type == Xlib.X.PropertyNotify and 
        event.atom == NET_ACTIVE_WINDOW): 
       break 

누군가를 위해 예제로 작성한보다 완전한 주석은 this gist입니다.