From f0218e7b4eab14142d87107b1e2e62e9efd25a15 Mon Sep 17 00:00:00 2001 From: Ottatop Date: Fri, 28 Jul 2023 21:38:12 -0500 Subject: [PATCH] Fix x11 context menu focus --- src/grab/move_grab.rs | 7 +++++++ src/grab/resize_grab.rs | 10 +++++++++- src/handlers/xwayland.rs | 11 ++++++++++- src/input.rs | 37 ++++++++++++++++++++++++++----------- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/grab/move_grab.rs b/src/grab/move_grab.rs index 2cdfe62..dcf22fc 100644 --- a/src/grab/move_grab.rs +++ b/src/grab/move_grab.rs @@ -100,6 +100,13 @@ impl PointerGrab> for MoveSurfaceGrab> { let new_loc = self.initial_window_loc.to_f64() + delta; data.space .map_element(self.window.clone(), new_loc.to_i32_round(), true); + if let WindowElement::X11(surface) = &self.window { + let geo = surface.geometry(); + let new_geo = Rectangle::from_loc_and_size(new_loc.to_i32_round(), geo.size); + surface + .configure(new_geo) + .expect("failed to configure x11 win"); + } } } diff --git a/src/grab/resize_grab.rs b/src/grab/resize_grab.rs index 262c99f..66ec617 100644 --- a/src/grab/resize_grab.rs +++ b/src/grab/resize_grab.rs @@ -330,7 +330,15 @@ pub fn handle_commit(state: &mut State, surface: &WlSurface) -> O } if new_loc.x.is_some() || new_loc.y.is_some() { - state.space.map_element(window, window_loc, false); + state.space.map_element(window.clone(), window_loc, false); + + if let WindowElement::X11(surface) = window { + let geo = surface.geometry(); + let new_geo = Rectangle::from_loc_and_size(window_loc, geo.size); + surface + .configure(new_geo) + .expect("failed to configure x11 win"); + } } Some(()) diff --git a/src/handlers/xwayland.rs b/src/handlers/xwayland.rs index 0a5fd0e..b96cd3b 100644 --- a/src/handlers/xwayland.rs +++ b/src/handlers/xwayland.rs @@ -32,6 +32,8 @@ impl XwmHandler for CalloopData { fn map_window_request(&mut self, _xwm: XwmId, window: X11Surface) { tracing::debug!("-----MAP WINDOW REQUEST"); + let win_type = window.window_type(); + tracing::debug!("window type is {win_type:?}"); // tracing::debug!("new x11 window from map_window_request"); // tracing::debug!("window popup is {}", window.is_popup()); // @@ -192,10 +194,13 @@ impl XwmHandler for CalloopData { // } fn mapped_override_redirect_window(&mut self, _xwm: XwmId, window: X11Surface) { + tracing::info!("MAPPED OVERRIDE REDIRECT WINDOW"); + let win_type = window.window_type(); + tracing::debug!("window type is {win_type:?}"); let loc = window.geometry().loc; let window = WindowElement::X11(window); // tracing::debug!("mapped_override_redirect_window to loc {loc:?}"); - self.state.space.map_element(window, loc, true); + self.state.space.map_element(window.clone(), loc, true); } fn unmapped_window(&mut self, _xwm: XwmId, window: X11Surface) { @@ -277,6 +282,10 @@ impl XwmHandler for CalloopData { geometry: Rectangle, _above: Option, ) { + if window.is_override_redirect() { + let keyboard = self.state.seat.get_keyboard().unwrap(); + keyboard.set_focus(&mut self.state, Some(FocusTarget::Window(WindowElement::X11(window.clone()))), SERIAL_COUNTER.next_serial()); + } // tracing::debug!("x11 configure_notify"); let Some(win) = self .state diff --git a/src/input.rs b/src/input.rs index 5e47fe5..a478e1f 100644 --- a/src/input.rs +++ b/src/input.rs @@ -74,6 +74,7 @@ impl State { // unfocus on windows. if ButtonState::Pressed == button_state { if let Some((window, window_loc)) = self.surface_under(pointer_loc) { + // tracing::debug!("button click on {window:?}"); const BUTTON_LEFT: u32 = 0x110; const BUTTON_RIGHT: u32 = 0x111; if self.move_mode { @@ -143,21 +144,29 @@ impl State { let FocusTarget::Window(window) = window else { return }; self.space.raise_element(&window, true); if let WindowElement::X11(surface) = &window { - self.xwm - .as_mut() - .expect("no xwm") - .raise_window(surface) - .expect("failed to raise x11 win"); - surface - .set_activated(true) - .expect("failed to set x11 win to activated"); + if !surface.is_override_redirect() { + self.xwm + .as_mut() + .expect("no xwm") + .raise_window(surface) + .expect("failed to raise x11 win"); + surface + .set_activated(true) + .expect("failed to set x11 win to activated"); + } } tracing::debug!( "wl_surface focus is some? {}", window.wl_surface().is_some() ); - keyboard.set_focus(self, Some(FocusTarget::Window(window.clone())), serial); + + // NOTE: *Do not* set keyboard focus to an override redirect window. This leads + // | to wonky things like right-click menus not correctly getting pointer + // | clicks or showing up at all. + if !matches!(&window, WindowElement::X11(surf) if surf.is_override_redirect()) { + keyboard.set_focus(self, Some(FocusTarget::Window(window.clone())), serial); + } self.space.elements().for_each(|window| { if let WindowElement::Wayland(window) = window { @@ -244,10 +253,15 @@ impl State { frame = frame.stop(Axis::Vertical); } + // tracing::debug!( + // "axis on current focus: {:?}", + // self.seat.get_pointer().unwrap().current_focus() + // ); + self.seat .get_pointer() .expect("Seat has no pointer") - .axis(self, frame); // FIXME: handle err + .axis(self, frame); } fn keyboard(&mut self, event: I::KeyboardKeyEvent) { @@ -392,7 +406,8 @@ impl State { // .map(|(_s, p)| (FocusTarget::Window(window.clone()), p + location)) // }); - tracing::debug!("surface_under_pointer: {surface_under_pointer:?}"); + // tracing::debug!("surface_under_pointer: {surface_under_pointer:?}"); + // tracing::debug!("pointer focus: {:?}", pointer.current_focus()); pointer.motion( self, surface_under_pointer,