X11环境下Electron应用程序化拖拽启动异常问题求助
在X11环境下重实现electron-click-drag-plugin的EWMH事件异常问题
我正在为自身Electron应用重实现electron-click-drag-plugin,但在X11环境下遭遇瓶颈。已成功发送EWMH事件,但效果不符合预期,具体症状:
- 发送事件后,窗口管理器进入异常状态,初期无明显异常,当光标移至目标窗口边缘时,窗口会随之移动,仿佛触发一次拖拽操作
- 进入该状态后难以退出,退出方式可能因窗口管理器而异
实现代码
x11rb版本
// x11rb let Ok((conn, _)) = x11rb::connect(None) else { let err_msg = cx.string("Failed to connect to X11 server"); return cx.throw(err_msg); }; let buf = handle.as_slice(cx); if buf.len() != 4 { let err_msg = cx.string("Invalid buffer size for window handle"); return cx.throw(err_msg); } let Some(window) = buf .get(0..4) .map(|b| u32::from_le_bytes(b.try_into().unwrap())) else { let err_msg = cx.string("Failed to parse window handle"); return cx.throw(err_msg); }; let Ok(query_pointer_reply) = query_pointer(&conn, window) .map_err(|_| ()) .and_then(|x| x.reply().map_err(|_| ())) else { let err_msg = cx.string("Failed to query pointer position"); return cx.throw(err_msg); }; let Ok(move_atom_reply) = intern_atom(&conn, false, "_NET_WM_MOVERESIZE".as_bytes()) .map_err(|_| ()) .and_then(|x| x.reply().map_err(|_| ())) else { let err_msg = cx.string("Failed to intern atom"); return cx.throw(err_msg); }; let roots = &conn.setup().roots; if roots.is_empty() { let err_msg = cx.string("No screens found"); return cx.throw(err_msg); } let root_window = roots[0].root; let event = ClientMessageEvent::new( 32, window, move_atom_reply.atom, ClientMessageData::from([ query_pointer_reply.root_x as u32, query_pointer_reply.root_y as u32, 8, // _NET_WM_MOVERESIZE_MOVE 1, // Button 1 (left mouse button) 0, ]), ); if let Err(err) = send_event( &conn, false, root_window, EventMask::SUBSTRUCTURE_REDIRECT | EventMask::SUBSTRUCTURE_NOTIFY, event, ) { let err_msg = cx.string(format!("Failed to send client message: {}", err)); return cx.throw(err_msg); } if let Err(err) = conn.flush() { let err_msg = cx.string(format!("Failed to flush X11 connection: {}", err)); return cx.throw(err_msg); }
Xlib动态绑定版本
// Dynamic resolves Xlib let display = x_open_display(std::ptr::null()); if display.is_null() { let err_msg = cx.string("Failed to open X display"); return cx.throw(err_msg); } let mut root_return: c_ulong = 0; let mut child_return: c_ulong = 0; let mut root_x: i32 = 0; let mut root_y: i32 = 0; let mut win_x: i32 = 0; let mut win_y: i32 = 0; let mut mask_return: u32 = 0; let query_res = x_query_pointer( display, window, &mut root_return, &mut child_return, &mut root_x, &mut root_y, &mut win_x, &mut win_y, &mut mask_return, ); if query_res == 0 { x_close_display(display); let err_msg = cx.string("XQueryPointer failed to query the pointer on the window"); return cx.throw(err_msg); } let move_atom = x_intern_atom(display, c"_NET_WM_MOVERESIZE".as_ptr(), 0); if move_atom == 0 { x_close_display(display); let err_msg = cx.string("XInternAtom failed to intern the _NET_WM_MOVERESIZE atom"); return cx.throw(err_msg); } let root_window = x_default_root_window(display); if root_window == 0 { x_close_display(display); let err_msg = cx.string("XDefaultRootWindow failed to get the default root window"); return cx.throw(err_msg); } let mut event = std::mem::zeroed::<XEvent>(); let xclient = &mut event.xclient; xclient.type_ = CLIENT_MESSAGE; xclient.window = window; xclient.message_type = move_atom; xclient.format = 32; xclient.data.l[0] = root_x as c_long; xclient.data.l[1] = root_y as c_long; xclient.data.l[2] = 8; // _NET_WM_MOVERESIZE_MOVE xclient.data.l[3] = 1; xclient.data.l[4] = 0; let send_res = x_send_event( display, root_window, 0, (SUBSTRUCTURE_REDIRECT_MASK | SUBSTRUCTURE_NOTIFY_MASK) as c_long, &mut event as *mut XEvent as *mut c_void, ); if send_res == 0 { x_close_display(display); let err_msg = cx.string("XSendEvent failed to send the _NET_WM_MOVERESIZE client message to the X server"); return cx.throw(err_msg); } x_flush(display); x_close_display(display);
已尝试的参数取值
button:0、1source_indication:0、1、2
环境信息
- Electron版本:v41.3.0
- 测试环境:
OS: EndeavourOS SonicDE version: 6.6.4 SonicDE framework version: 6.25.0 Qt version: 6.11.0 Kernel version: 6.19.11-arch1-1 (64 位) Desktop Environment: X11 (The X.Org Foundation) 1.21.1 CPU: 4 × Intel® Core™ i9-14900HX RAM: 3.8 GiB available GPU: llvmpipe Vendor: VMware, Inc. Product Name: VMware Virtual Platform System Version: None
内容的提问来源于stack exchange,提问作者Yu Ling
相关产品推荐
相关产品推荐

