From 045698e6ca317f2647d2fdb3d459e0405d0ad6cc Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sun, 27 Mar 2022 07:10:47 -0700 Subject: [PATCH] x11: query focus prior to painting if we don't know focus state We don't assume that we start up focused, and some WM don't tell us our focus state, so prior to painting, if we don't know the focus state, explicitly query it and synthesize a focus change event. refs: https://github.com/wez/wezterm/issues/1757 --- window/src/os/x11/window.rs | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/window/src/os/x11/window.rs b/window/src/os/x11/window.rs index 492faa7c4..691fb6a6b 100644 --- a/window/src/os/x11/window.rs +++ b/window/src/os/x11/window.rs @@ -65,7 +65,7 @@ pub(crate) struct XWindowInner { config: ConfigHandle, appearance: Appearance, title: String, - has_focus: bool, + has_focus: Option, last_cursor_position: Rect, invalidated: bool, paint_throttled: bool, @@ -209,6 +209,19 @@ impl XWindowInner { } else { self.invalidated = false; + if self.has_focus.is_none() { + log::trace!( + "About to paint, but we've never received a FOCUS_IN/FOCUS_OUT \ + event; querying WM to determine focus state" + ); + + let focus = xcb::xproto::get_input_focus(&self.conn()).get_reply()?; + let focused = focus.focus() == self.window_id; + log::trace!("Do I have focus? {}", focused); + self.has_focus.replace(focused); + self.events.dispatch(WindowEvent::FocusChanged(focused)); + } + if !self.dispatched_any_resize { self.dispatched_any_resize = true; @@ -450,13 +463,13 @@ impl XWindowInner { } } xcb::FOCUS_IN => { - self.has_focus = true; + self.has_focus.replace(true); self.update_ime_position(); log::trace!("Calling focus_change(true)"); self.events.dispatch(WindowEvent::FocusChanged(true)); } xcb::FOCUS_OUT => { - self.has_focus = false; + self.has_focus.replace(false); log::trace!("Calling focus_change(false)"); self.events.dispatch(WindowEvent::FocusChanged(false)); } @@ -906,7 +919,7 @@ impl XWindow { copy_and_paste: CopyAndPaste::default(), cursors: CursorInfo::new(&config, &conn), config: config.clone(), - has_focus: false, + has_focus: None, last_cursor_position: Rect::default(), paint_throttled: false, invalidated: false, @@ -1037,7 +1050,7 @@ impl XWindowInner { } fn update_ime_position(&mut self) { - if !self.has_focus { + if !self.has_focus.unwrap_or(false) { return; } self.conn().ime.borrow_mut().update_pos(