2017-04-26 6 views
1

XCBを使用して、X11ウィンドウに他のプロパティのうち、プロセスのPIDを問い合わせています。次のように非文字列の属性を様々な得るために、私のコードは次のとおりです。存在しない_NET_WM_PIDについてxcb_get_property_replyからエラーを受け取ることはできません

xcb_window_t wid; 
xcb_connection_t * conn; 

template <typename T> 
T get_property(xcb_atom_t property, xcb_atom_t type, size_t len = sizeof(T)) { 
    xcb_generic_error_t *err = nullptr; // can't use unique_ptr here because get_property_reply overwrites pointer value 

    /* 
    Specifies how many 32-bit multiples of data should be retrieved 
    (e.g. if you set long_length to 4, you will receive 16 bytes of data). 
    */ 
    uint32_t ret_size = 
     len/sizeof(uint32_t) /*integer division, like floor()*/ + 
     !!(len%sizeof(uint32_t)) /*+1 if there was a remainder*/; 

    xcb_get_property_cookie_t cookie = xcb_get_property(
     conn, 0, wid, property, type, 0, ret_size 
    ); 

    std::unique_ptr<xcb_get_property_reply_t,decltype(&free)> reply {xcb_get_property_reply(conn, cookie, &err),&free}; 
    if (!reply) { 
     free(err); 
     throw std::runtime_error("xcb_get_property returned error"); 
    } 

    return *reinterpret_cast<T*>(
     xcb_get_property_value(
      reply.get() 
     ) 
    ); 
} 

xcb_atom_t NET_WM_PID; // initialized using xcb_intern_atom 
// according to libxcb-ewmh, CARDINALs are uint32_t 
pid_t pid = get_property<uint32_t>(NET_WM_PID, XCB_ATOM_CARDINAL); 

エラー処理はxcb-requests(3)から再生されます。ウィンドウに_NET_WM_PIDプロパティーセットがないときに問題が発生します(例えば、Workerファイルマネージャーはそうしません)。その場合、をxcb_get_property_replyから非null errに変更する代わりに、XCB要求のシーケンス番号に等しい数値の回答が得られます。 _NET_WM_PIDまたはタイプCARDINALの他のプロパティがウィンドウに設定されていないかどうかを正しく確認するにはどうすればよいですか?

答えて

1

プロパティの不在はエラーではありません。プロパティーが設定されていない場合、応答の形式、タイプ、および長さはすべてゼロになります。おそらく、すべてをチェックして、期待する価値があることを確認したいでしょう。

+0

ありがとうございました!私のテンプレート関数では、要求された長さと 'xcb_get_property_value_length(reply.get())'の両方がゼロでないことを確認し、そうでなければスローします。 – aitap

関連する問題