x11: Differentiate between mouse and keyboard focus (#13943)
Fixes https://github.com/zed-industries/zed/issues/13897 Release Notes: - N/A
This commit is contained in:
parent
032b203519
commit
75377bbe0f
2 changed files with 28 additions and 12 deletions
|
@ -115,7 +115,8 @@ pub struct X11ClientState {
|
||||||
pub(crate) _resource_database: Database,
|
pub(crate) _resource_database: Database,
|
||||||
pub(crate) atoms: XcbAtoms,
|
pub(crate) atoms: XcbAtoms,
|
||||||
pub(crate) windows: HashMap<xproto::Window, WindowRef>,
|
pub(crate) windows: HashMap<xproto::Window, WindowRef>,
|
||||||
pub(crate) focused_window: Option<xproto::Window>,
|
pub(crate) mouse_focused_window: Option<xproto::Window>,
|
||||||
|
pub(crate) keyboard_focused_window: Option<xproto::Window>,
|
||||||
pub(crate) xkb: xkbc::State,
|
pub(crate) xkb: xkbc::State,
|
||||||
pub(crate) ximc: Option<X11rbClient<Rc<XCBConnection>>>,
|
pub(crate) ximc: Option<X11rbClient<Rc<XCBConnection>>>,
|
||||||
pub(crate) xim_handler: Option<XimHandler>,
|
pub(crate) xim_handler: Option<XimHandler>,
|
||||||
|
@ -151,7 +152,12 @@ impl X11ClientStatePtr {
|
||||||
x_window
|
x_window
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if state.mouse_focused_window == Some(x_window) {
|
||||||
|
state.mouse_focused_window = None;
|
||||||
|
}
|
||||||
|
if state.keyboard_focused_window == Some(x_window) {
|
||||||
|
state.keyboard_focused_window = None;
|
||||||
|
}
|
||||||
state.cursor_styles.remove(&x_window);
|
state.cursor_styles.remove(&x_window);
|
||||||
|
|
||||||
if state.windows.is_empty() {
|
if state.windows.is_empty() {
|
||||||
|
@ -320,7 +326,8 @@ impl X11Client {
|
||||||
_resource_database: resource_database,
|
_resource_database: resource_database,
|
||||||
atoms,
|
atoms,
|
||||||
windows: HashMap::default(),
|
windows: HashMap::default(),
|
||||||
focused_window: None,
|
mouse_focused_window: None,
|
||||||
|
keyboard_focused_window: None,
|
||||||
xkb: xkb_state,
|
xkb: xkb_state,
|
||||||
ximc,
|
ximc,
|
||||||
xim_handler,
|
xim_handler,
|
||||||
|
@ -361,7 +368,7 @@ impl X11Client {
|
||||||
.push(AttributeName::ClientWindow, xim_handler.window)
|
.push(AttributeName::ClientWindow, xim_handler.window)
|
||||||
.push(AttributeName::FocusWindow, xim_handler.window);
|
.push(AttributeName::FocusWindow, xim_handler.window);
|
||||||
|
|
||||||
let window_id = state.focused_window;
|
let window_id = state.keyboard_focused_window;
|
||||||
drop(state);
|
drop(state);
|
||||||
if let Some(window_id) = window_id {
|
if let Some(window_id) = window_id {
|
||||||
let window = self.get_window(window_id).unwrap();
|
let window = self.get_window(window_id).unwrap();
|
||||||
|
@ -558,19 +565,19 @@ impl X11Client {
|
||||||
let window = self.get_window(event.window)?;
|
let window = self.get_window(event.window)?;
|
||||||
window.refresh();
|
window.refresh();
|
||||||
}
|
}
|
||||||
Event::FocusIn(event) => {
|
Event::FocusIn(event) if event.mode == xproto::NotifyMode::NORMAL => {
|
||||||
let window = self.get_window(event.event)?;
|
let window = self.get_window(event.event)?;
|
||||||
window.set_focused(true);
|
window.set_focused(true);
|
||||||
let mut state = self.0.borrow_mut();
|
let mut state = self.0.borrow_mut();
|
||||||
state.focused_window = Some(event.event);
|
state.keyboard_focused_window = Some(event.event);
|
||||||
drop(state);
|
drop(state);
|
||||||
self.enable_ime();
|
self.enable_ime();
|
||||||
}
|
}
|
||||||
Event::FocusOut(event) => {
|
Event::FocusOut(event) if event.mode == xproto::NotifyMode::NORMAL => {
|
||||||
let window = self.get_window(event.event)?;
|
let window = self.get_window(event.event)?;
|
||||||
window.set_focused(false);
|
window.set_focused(false);
|
||||||
let mut state = self.0.borrow_mut();
|
let mut state = self.0.borrow_mut();
|
||||||
state.focused_window = None;
|
state.keyboard_focused_window = None;
|
||||||
if let Some(compose_state) = state.compose_state.as_mut() {
|
if let Some(compose_state) = state.compose_state.as_mut() {
|
||||||
compose_state.reset();
|
compose_state.reset();
|
||||||
}
|
}
|
||||||
|
@ -594,7 +601,7 @@ impl X11Client {
|
||||||
if state.modifiers == modifiers {
|
if state.modifiers == modifiers {
|
||||||
drop(state);
|
drop(state);
|
||||||
} else {
|
} else {
|
||||||
let focused_window_id = state.focused_window?;
|
let focused_window_id = state.keyboard_focused_window?;
|
||||||
state.modifiers = modifiers;
|
state.modifiers = modifiers;
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
|
@ -844,12 +851,18 @@ impl X11Client {
|
||||||
valuator_idx += 1;
|
valuator_idx += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Event::XinputEnter(event) if event.mode == xinput::NotifyMode::NORMAL => {
|
||||||
|
let window = self.get_window(event.event)?;
|
||||||
|
window.set_focused(true);
|
||||||
|
let mut state = self.0.borrow_mut();
|
||||||
|
state.mouse_focused_window = Some(event.event);
|
||||||
|
}
|
||||||
Event::XinputLeave(event) if event.mode == xinput::NotifyMode::NORMAL => {
|
Event::XinputLeave(event) if event.mode == xinput::NotifyMode::NORMAL => {
|
||||||
self.0.borrow_mut().scroll_x = None; // Set last scroll to `None` so that a large delta isn't created if scrolling is done outside the window (the valuator is global)
|
self.0.borrow_mut().scroll_x = None; // Set last scroll to `None` so that a large delta isn't created if scrolling is done outside the window (the valuator is global)
|
||||||
self.0.borrow_mut().scroll_y = None;
|
self.0.borrow_mut().scroll_y = None;
|
||||||
|
|
||||||
let window = self.get_window(event.event)?;
|
|
||||||
let mut state = self.0.borrow_mut();
|
let mut state = self.0.borrow_mut();
|
||||||
|
state.mouse_focused_window = None;
|
||||||
let pressed_button = pressed_button_from_mask(event.buttons[0]);
|
let pressed_button = pressed_button_from_mask(event.buttons[0]);
|
||||||
let position = point(
|
let position = point(
|
||||||
px(event.event_x as f32 / u16::MAX as f32 / state.scale_factor),
|
px(event.event_x as f32 / u16::MAX as f32 / state.scale_factor),
|
||||||
|
@ -859,11 +872,13 @@ impl X11Client {
|
||||||
state.modifiers = modifiers;
|
state.modifiers = modifiers;
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
|
let window = self.get_window(event.event)?;
|
||||||
window.handle_input(PlatformInput::MouseExited(crate::MouseExitEvent {
|
window.handle_input(PlatformInput::MouseExited(crate::MouseExitEvent {
|
||||||
pressed_button,
|
pressed_button,
|
||||||
position,
|
position,
|
||||||
modifiers,
|
modifiers,
|
||||||
}));
|
}));
|
||||||
|
window.set_focused(false);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
@ -1046,7 +1061,7 @@ impl LinuxClient for X11Client {
|
||||||
|
|
||||||
fn set_cursor_style(&self, style: CursorStyle) {
|
fn set_cursor_style(&self, style: CursorStyle) {
|
||||||
let mut state = self.0.borrow_mut();
|
let mut state = self.0.borrow_mut();
|
||||||
let Some(focused_window) = state.focused_window else {
|
let Some(focused_window) = state.mouse_focused_window else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let current_style = state
|
let current_style = state
|
||||||
|
@ -1294,7 +1309,7 @@ impl LinuxClient for X11Client {
|
||||||
|
|
||||||
fn active_window(&self) -> Option<AnyWindowHandle> {
|
fn active_window(&self) -> Option<AnyWindowHandle> {
|
||||||
let state = self.0.borrow();
|
let state = self.0.borrow();
|
||||||
state.focused_window.and_then(|focused_window| {
|
state.keyboard_focused_window.and_then(|focused_window| {
|
||||||
state
|
state
|
||||||
.windows
|
.windows
|
||||||
.get(&focused_window)
|
.get(&focused_window)
|
||||||
|
|
|
@ -450,6 +450,7 @@ impl X11WindowState {
|
||||||
xinput::XIEventMask::MOTION
|
xinput::XIEventMask::MOTION
|
||||||
| xinput::XIEventMask::BUTTON_PRESS
|
| xinput::XIEventMask::BUTTON_PRESS
|
||||||
| xinput::XIEventMask::BUTTON_RELEASE
|
| xinput::XIEventMask::BUTTON_RELEASE
|
||||||
|
| xinput::XIEventMask::ENTER
|
||||||
| xinput::XIEventMask::LEAVE,
|
| xinput::XIEventMask::LEAVE,
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue