linux/x11: Restore differentiation of mouse/keyboard focus (#13995)
This restores https://github.com/zed-industries/zed/pull/13943 which was reverted in #13974 because it was possible to get in a state where focus could not be restored on a window. In this PR there's an additional change: `FocusIn` and `FocusOut` events are always handled, even if the `event.mode` is not "NORMAL". In my testing, `alt-tabbing` between windows didn't produce `FocusIn` and `FocusOut` events when we had that check. Now, with the check removed, it's possible to switch focus between two windows again with `alt-tab`. Release Notes: - N/A --------- Co-authored-by: Conrad <conrad@zed.dev> Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
parent
c732865fc5
commit
ee623f77c1
9 changed files with 127 additions and 17 deletions
|
@ -541,6 +541,7 @@ pub struct Window {
|
|||
appearance: WindowAppearance,
|
||||
appearance_observers: SubscriberSet<(), AnyObserver>,
|
||||
active: Rc<Cell<bool>>,
|
||||
hovered: Rc<Cell<bool>>,
|
||||
pub(crate) dirty: Rc<Cell<bool>>,
|
||||
pub(crate) needs_present: Rc<Cell<bool>>,
|
||||
pub(crate) last_input_timestamp: Rc<Cell<Instant>>,
|
||||
|
@ -672,6 +673,7 @@ impl Window {
|
|||
let text_system = Arc::new(WindowTextSystem::new(cx.text_system().clone()));
|
||||
let dirty = Rc::new(Cell::new(true));
|
||||
let active = Rc::new(Cell::new(platform_window.is_active()));
|
||||
let hovered = Rc::new(Cell::new(platform_window.is_hovered()));
|
||||
let needs_present = Rc::new(Cell::new(false));
|
||||
let next_frame_callbacks: Rc<RefCell<Vec<FrameCallback>>> = Default::default();
|
||||
let last_input_timestamp = Rc::new(Cell::new(Instant::now()));
|
||||
|
@ -778,7 +780,17 @@ impl Window {
|
|||
.log_err();
|
||||
}
|
||||
}));
|
||||
|
||||
platform_window.on_hover_status_change(Box::new({
|
||||
let mut cx = cx.to_async();
|
||||
move |active| {
|
||||
handle
|
||||
.update(&mut cx, |_, cx| {
|
||||
cx.window.hovered.set(active);
|
||||
cx.refresh();
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
}));
|
||||
platform_window.on_input({
|
||||
let mut cx = cx.to_async();
|
||||
Box::new(move |event| {
|
||||
|
@ -829,6 +841,7 @@ impl Window {
|
|||
appearance,
|
||||
appearance_observers: SubscriberSet::new(),
|
||||
active,
|
||||
hovered,
|
||||
dirty,
|
||||
needs_present,
|
||||
last_input_timestamp,
|
||||
|
@ -1222,6 +1235,17 @@ impl<'a> WindowContext<'a> {
|
|||
self.window.active.get()
|
||||
}
|
||||
|
||||
/// Returns whether this window is considered to be the window
|
||||
/// that currently owns the mouse cursor.
|
||||
/// On mac, this is equivalent to `is_window_active`.
|
||||
pub fn is_window_hovered(&self) -> bool {
|
||||
if cfg!(target_os = "linux") {
|
||||
self.window.hovered.get()
|
||||
} else {
|
||||
self.is_window_active()
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggle zoom on the window.
|
||||
pub fn zoom_window(&self) {
|
||||
self.window.platform_window.zoom();
|
||||
|
@ -2980,7 +3004,7 @@ impl<'a> WindowContext<'a> {
|
|||
|
||||
fn reset_cursor_style(&self) {
|
||||
// Set the cursor only if we're the active window.
|
||||
if self.is_window_active() {
|
||||
if self.is_window_hovered() {
|
||||
let style = self
|
||||
.window
|
||||
.rendered_frame
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue