diff --git a/window/src/os/x11/connection.rs b/window/src/os/x11/connection.rs index 0a11d75d583..3f078b82f08 100644 --- a/window/src/os/x11/connection.rs +++ b/window/src/os/x11/connection.rs @@ -70,6 +70,7 @@ pub struct XConnection { pub atom_net_active_window: Atom, pub(crate) xrm: RefCell>, pub(crate) windows: RefCell>>>, + pub(crate) child_to_parent_id: RefCell>, should_terminate: RefCell, pub(crate) visual: xcb::x::Visualtype, pub(crate) depth: u8, @@ -578,6 +579,10 @@ impl XConnection { self.windows.borrow().get(&window_id).map(Arc::clone) } + fn parent_id_by_child_id(&self, child_id: xcb::x::Window) -> Option { + self.child_to_parent_id.borrow().get(&child_id).copied() + } + fn dispatch_pending_events(&self) -> anyhow::Result<()> { for window in self.windows.borrow().values() { let mut inner = window.lock().unwrap(); @@ -595,6 +600,11 @@ impl XConnection { if let Some(window) = self.window_by_id(window_id) { let mut inner = window.lock().unwrap(); inner.dispatch_event(event)?; + } else if let Some(parent_id) = self.parent_id_by_child_id(window_id) { + if let Some(window) = self.window_by_id(parent_id) { + let mut inner = window.lock().unwrap(); + inner.dispatch_event(event)?; + } } Ok(()) } @@ -804,6 +814,7 @@ impl XConnection { atom_xsel_data, atom_targets, windows: RefCell::new(HashMap::new()), + child_to_parent_id: RefCell::new(HashMap::new()), should_terminate: RefCell::new(false), depth, visual, diff --git a/window/src/os/x11/window.rs b/window/src/os/x11/window.rs index 8b434c32a89..58ec4f8936f 100644 --- a/window/src/os/x11/window.rs +++ b/window/src/os/x11/window.rs @@ -792,6 +792,7 @@ impl XWindowInner { Event::X(xcb::x::Event::DestroyNotify(_)) => { self.events.dispatch(WindowEvent::Destroyed); conn.windows.borrow_mut().remove(&self.window_id); + conn.child_to_parent_id.borrow_mut().remove(&self.child_id); } Event::X(xcb::x::Event::SelectionClear(e)) => { self.selection_clear(e)?; @@ -1414,8 +1415,7 @@ impl XWindow { xcb::x::Cw::BackPixel(0), // transparent background xcb::x::Cw::BorderPixel(screen.black_pixel()), xcb::x::Cw::EventMask( - xcb::x::EventMask::EXPOSURE - | xcb::x::EventMask::FOCUS_CHANGE + xcb::x::EventMask::FOCUS_CHANGE | xcb::x::EventMask::KEY_PRESS | xcb::x::EventMask::BUTTON_PRESS | xcb::x::EventMask::BUTTON_RELEASE @@ -1449,6 +1449,7 @@ impl XWindow { xcb::x::Cw::BackPixel(0), // transparent background xcb::x::Cw::BorderPixel(screen.black_pixel()), xcb::x::Cw::BitGravity(xcb::x::Gravity::NorthWest), + xcb::x::Cw::EventMask(xcb::x::EventMask::EXPOSURE), xcb::x::Cw::Colormap(color_map_id), ], }) @@ -1538,6 +1539,9 @@ impl XWindow { let window_handle = Window::X11(XWindow::from_id(window_id)); conn.windows.borrow_mut().insert(window_id, window); + conn.child_to_parent_id + .borrow_mut() + .insert(child_id, window_id); window_handle.set_title(name); // Before we map the window, flush to ensure that all of the other properties @@ -1581,6 +1585,10 @@ impl XWindowInner { // Drop impl, and that cannot succeed after we've // destroyed the window at the X11 level. self.conn().windows.borrow_mut().remove(&self.window_id); + self.conn() + .child_to_parent_id + .borrow_mut() + .remove(&self.child_id); // Unmap the window first: calling DestroyWindow here may race // with some requests made either by EGL or the IME, but I haven't