如何给出带有rust-xcb的窗口ID的X窗口类?

时间:2017-06-29 19:10:51

标签: casting rust x11 xcb

我尝试使用rust-xcb来获取窗口ID的窗口。

fn get_class(conn: &xcb::Connection, id: &i32) {
    let window: xcb::xproto::Window = *id as u32;
    let class_prop: xcb::xproto::Atom = 67; // XCB_ATOM_WM_CLASS from xproto.h
    let cookie = xcb::xproto::get_property(&conn, false, window, class_prop, 0, 0, 2);
    match cookie.get_reply() {
        Ok(reply) => {
            let x: &[std::os::raw::c_void] = reply.value();
            println!("reply is {:?}", x[0]);
        }   
        Err(err) => println!("err {:?}", err),
    }
}

文档有点稀疏,并没有令人难以置信的帮助,尽管我确实发现了GetPropertyReply和它所包含的xcb_get_property_reply_t

我看了this answer in JavaScript,但我不知道Rust中的ctypes等价物是什么。我尝试将&[c_void]转换为&strString

 ...
 Ok(reply) => {
     let len = reply.value_len() as usize;
     let buf = reply.value() as &str;
     println!("{}", buf.slice_unchecked(0, len)); // this seems redundant
 }   
 ...

但它返回

error: non-scalar cast: `&[_]` as `&str`

我尝试将&[c_void]转换为&[u8],然后将Vec收集到String,这类似:

  ...
  Ok(reply) => {
      let value : &[u8] = reply.value();
      let buf : String = value.into_iter().map(|i| *i as char).collect();
      println!("\t{:?}", buf);
  }
  ...

但我现在得到了奇怪的结果。例如,当我在Chrome上使用xprop时,我会看到" google-chrome"但对我来说,它只是显示" google-c"和" roxterm"出现在" roxterm \ u {0}"。我在猜测" \ u {0}"是与Unicode相关的东西,但我不确定,我也不知道为什么这些东西正在被连接起来。也许我必须再次检查回复?

1 个答案:

答案 0 :(得分:0)

这是我的更新功能:

fn get_class(conn: &Connection, id: &i32) -> String {
    let window: xproto::Window = *id as u32;
    let long_length: u32 = 8;
    let mut long_offset: u32 = 0;
    let mut buf = Vec::new();
    loop {
        let cookie = xproto::get_property(
            &conn,
            false,
            window,
            xproto::ATOM_WM_CLASS,
            xproto::ATOM_STRING,
            long_offset,
            long_length,
        );
        match cookie.get_reply() {
            Ok(reply) => {
                let value: &[u8] = reply.value();
                buf.extend_from_slice(value);
                match reply.bytes_after() {
                    0 => break,
                    _ => {
                        let len = reply.value_len();
                        long_offset += len / 4;
                    }   
                }
            }   
            Err(err) => {
                println!("{:?}", err);
                break;
            }   
        }
    }
    let result = String::from_utf8(buf).unwrap();
    let results: Vec<&str> = result.split('\0').collect();
    results[0].to_string()
}

这个问题有三个主要部分:

  1. 我将xproto::get_property()放入循环中,以便检查reply.bytes_after()并相应地调整long_offset。我认为通过适当的long_length通常只会有一次阅读,但只是安全。
  2. 正如@ peter-hall所说,转换&[u8] -> String应该使用String::from_utf8来完成,Vec需要let mut buf = Vec::new();所以在使用buf.extend_from_slice
  3. 创建结果字符串之前,我String::from_utf8(buf).unwrap()\0在循环上
  4. 根据this random page WM_CLASS实际上是两个连续的以空字符结尾的字符串,因此我将结果分成 CPXPARAM_MIP_Strategy_CallbackReducedLP 0 Found incumbent of value 0.000000 after 0.00 sec. (0.70 ticks) Tried aggregator 1 time. MIP Presolve eliminated 570 rows and 3 columns. MIP Presolve modified 88 coefficients. Reduced MIP has 390 rows, 29291 columns, and 76482 nonzeros. Reduced MIP has 29291 binaries, 0 generals, 0 SOSs, and 0 indicators. Presolve time = 0.06 sec. (49.60 ticks) Tried aggregator 1 time. Reduced MIP has 390 rows, 29291 columns, and 76482 nonzeros. Reduced MIP has 29291 binaries, 0 generals, 0 SOSs, and 0 indicators. Presolve time = 0.04 sec. (31.47 ticks) Probing time = 0.02 sec. (1.36 ticks) MIP emphasis: balance optimality and feasibility. MIP search method: dynamic search. Parallel mode: deterministic, using up to 8 threads. Root relaxation solution time = 0.03 sec. (17.59 ticks) Nodes Cuts/ Node Left Objective IInf Best Integer Best Bound ItCnt Gap * 0+ 0 0.0000 -395.1814 --- * 0+ 0 -291.2283 -395.1814 35.69% * 0 0 integral 0 -372.2283 -372.2283 201 0.00% Elapsed time = 0.21 sec. (131.64 ticks, tree = 0.00 MB, solutions = 3) Root node processing (before b&c): Real time = 0.21 sec. (133.18 ticks) Parallel b&c, 8 threads: Real time = 0.00 sec. (0.00 ticks) Sync time (average) = 0.00 sec. Wait time (average) = 0.00 sec. ------------ Total (root+branch&cut) = 0.21 sec. (133.18 ticks) 并获取第一个值。
  5. 我可能只是在寻找错误的地方,但是xcb的文档非常糟糕..