aaaa
This commit is contained in:
@@ -7,10 +7,12 @@ use x11rb::atom_manager;
|
||||
use x11rb::connection::Connection;
|
||||
use x11rb::protocol::xproto::{
|
||||
AtomEnum, ChangeWindowAttributesAux, ClientMessageEvent, ConfigureWindowAux,
|
||||
ConnectionExt as XprotoConnectionExt, EventMask, StackMode,
|
||||
ConnectionExt as XprotoConnectionExt, EventMask, StackMode, UnmapNotifyEvent,
|
||||
UNMAP_NOTIFY_EVENT,
|
||||
};
|
||||
use x11rb::protocol::Event;
|
||||
use x11rb::rust_connection::RustConnection;
|
||||
use x11rb::wrapper::ConnectionExt as _;
|
||||
|
||||
atom_manager! {
|
||||
pub Atoms: AtomsCookie {
|
||||
@@ -172,9 +174,16 @@ pub async fn app_launch(
|
||||
// Detach: we don't wait() — Tauri exiting will SIGHUP it via the X11 parent.
|
||||
std::mem::forget(child);
|
||||
|
||||
eprintln!(
|
||||
"[infinite] app_launch: command={:?} pid={} tauri_xid={:#x}",
|
||||
opts.command, root_pid, parent_xid
|
||||
);
|
||||
|
||||
let client_xid = wait_for_window_by_pid(&c, root_pid, Duration::from_secs(20))
|
||||
.ok_or_else(|| "could not find window for launched process".to_string())?;
|
||||
|
||||
eprintln!("[infinite] found client window {:#x} for pid {}", client_xid, root_pid);
|
||||
|
||||
embed_window(&c, client_xid, parent_xid)?;
|
||||
|
||||
let title = read_window_title(&c, client_xid).unwrap_or_else(|| opts.command.clone());
|
||||
@@ -279,6 +288,30 @@ pub fn app_close(app: AppHandle, state: State<'_, X11State>, xid: u32) -> Result
|
||||
}
|
||||
|
||||
fn embed_window(c: &X11Conn, client_xid: u32, parent_xid: u32) -> Result<(), String> {
|
||||
eprintln!(
|
||||
"[infinite] embed: client={:#x} -> parent={:#x}",
|
||||
client_xid, parent_xid
|
||||
);
|
||||
|
||||
// XWithdrawWindow protocol: unmap then send synthetic UnmapNotify to root so
|
||||
// the WM unmanages this window. Without this step Mutter et al. keep treating
|
||||
// it as a top-level even after reparenting.
|
||||
let _ = c.conn.unmap_window(client_xid);
|
||||
let unmap_event = UnmapNotifyEvent {
|
||||
response_type: UNMAP_NOTIFY_EVENT,
|
||||
sequence: 0,
|
||||
event: c.root,
|
||||
window: client_xid,
|
||||
from_configure: false,
|
||||
};
|
||||
let _ = c.conn.send_event(
|
||||
false,
|
||||
c.root,
|
||||
EventMask::SUBSTRUCTURE_NOTIFY | EventMask::SUBSTRUCTURE_REDIRECT,
|
||||
unmap_event,
|
||||
);
|
||||
let _ = c.conn.sync();
|
||||
|
||||
// Listen for destroy / property changes on the embedded window.
|
||||
c.conn
|
||||
.change_window_attributes(
|
||||
@@ -292,8 +325,7 @@ fn embed_window(c: &X11Conn, client_xid: u32, parent_xid: u32) -> Result<(), Str
|
||||
c.conn
|
||||
.reparent_window(client_xid, parent_xid, 0, 0)
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
c.conn.map_window(client_xid).map_err(|e| e.to_string())?;
|
||||
let _ = c.conn.sync();
|
||||
|
||||
// Stack above the webview's GDK X11 surface (siblings under Tauri toplevel).
|
||||
c.conn
|
||||
@@ -303,6 +335,7 @@ fn embed_window(c: &X11Conn, client_xid: u32, parent_xid: u32) -> Result<(), Str
|
||||
)
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
c.conn.map_window(client_xid).map_err(|e| e.to_string())?;
|
||||
c.conn.flush().map_err(|e| e.to_string())?;
|
||||
|
||||
// Inform the client it is now embedded (XEmbed protocol).
|
||||
@@ -315,6 +348,26 @@ fn embed_window(c: &X11Conn, client_xid: u32, parent_xid: u32) -> Result<(), Str
|
||||
let _ = c.conn.send_event(false, client_xid, EventMask::NO_EVENT, event);
|
||||
c.conn.flush().map_err(|e| e.to_string())?;
|
||||
|
||||
// Verify the reparent took effect at the X11 level. If it didn't, the call
|
||||
// succeeded but something (WM, compositor) reverted it.
|
||||
let tree = c
|
||||
.conn
|
||||
.query_tree(client_xid)
|
||||
.map_err(|e| e.to_string())?
|
||||
.reply()
|
||||
.map_err(|e| e.to_string())?;
|
||||
eprintln!(
|
||||
"[infinite] after reparent: parent={:#x} (wanted {:#x}), root={:#x}",
|
||||
tree.parent, parent_xid, tree.root
|
||||
);
|
||||
if tree.parent != parent_xid {
|
||||
return Err(format!(
|
||||
"reparent did not stick: window {:#x} parent is {:#x}, not {:#x}. \
|
||||
Likely a Wayland session — try logging in to 'Ubuntu on Xorg'.",
|
||||
client_xid, tree.parent, parent_xid
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user