gpui: Fix window cursor style flickering (#32596)
Closes #32592 Follow-up to #31965 This PR fixes the cursor style flickering on Linux systems. The issue arose since the window cursor style was not reused anymore for subsequent frames after the changes in #31965. This works on MacOS for hiding cursors, since they are hidden until the next mouse movement occurs, which is not the case for other systems. This PR re-adds this whilst keeping the fixes applied in #31965. We now determine the first cursor style that is hovered and continue searching for a cursor style that should be applied globally. If one to apply for the whole window is found, we return that cursor style early instead. Alternatively, we could store window cursor style request in a vector similar to normal cursor styles. That would require more memory in exchange for fewer checks which cursor style to apply. I preferred the approach here, though, but can change this should the other method be preferred. CC @smitbarmase since you assigned yourself that issue. Release Notes: - Fixed an issue where the cursor would flicker whilst typing.
This commit is contained in:
parent
2d4e427b45
commit
7ecad2bef9
1 changed files with 17 additions and 13 deletions
|
@ -24,6 +24,8 @@ use core_video::pixel_buffer::CVPixelBuffer;
|
|||
use derive_more::{Deref, DerefMut};
|
||||
use futures::FutureExt;
|
||||
use futures::channel::oneshot;
|
||||
use itertools::FoldWhile::{Continue, Done};
|
||||
use itertools::Itertools;
|
||||
use parking_lot::RwLock;
|
||||
use raw_window_handle::{HandleError, HasDisplayHandle, HasWindowHandle};
|
||||
use refineable::Refineable;
|
||||
|
@ -408,7 +410,7 @@ pub(crate) type AnyMouseListener =
|
|||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct CursorStyleRequest {
|
||||
pub(crate) hitbox_id: HitboxId,
|
||||
pub(crate) hitbox_id: Option<HitboxId>,
|
||||
pub(crate) style: CursorStyle,
|
||||
}
|
||||
|
||||
|
@ -622,7 +624,6 @@ pub(crate) struct Frame {
|
|||
pub(crate) input_handlers: Vec<Option<PlatformInputHandler>>,
|
||||
pub(crate) tooltip_requests: Vec<Option<TooltipRequest>>,
|
||||
pub(crate) cursor_styles: Vec<CursorStyleRequest>,
|
||||
window_cursor_style: Option<CursorStyle>,
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub(crate) debug_bounds: FxHashMap<String, Bounds<Pixels>>,
|
||||
#[cfg(any(feature = "inspector", debug_assertions))]
|
||||
|
@ -667,7 +668,6 @@ impl Frame {
|
|||
input_handlers: Vec::new(),
|
||||
tooltip_requests: Vec::new(),
|
||||
cursor_styles: Vec::new(),
|
||||
window_cursor_style: None,
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
debug_bounds: FxHashMap::default(),
|
||||
|
@ -693,7 +693,6 @@ impl Frame {
|
|||
self.window_control_hitboxes.clear();
|
||||
self.deferred_draws.clear();
|
||||
self.focus = None;
|
||||
self.window_cursor_style = None;
|
||||
|
||||
#[cfg(any(feature = "inspector", debug_assertions))]
|
||||
{
|
||||
|
@ -703,14 +702,16 @@ impl Frame {
|
|||
}
|
||||
|
||||
pub(crate) fn cursor_style(&self, window: &Window) -> Option<CursorStyle> {
|
||||
self.window_cursor_style.or_else(|| {
|
||||
self.cursor_styles.iter().rev().find_map(|request| {
|
||||
request
|
||||
.hitbox_id
|
||||
.is_hovered(window)
|
||||
.then_some(request.style)
|
||||
})
|
||||
self.cursor_styles
|
||||
.iter()
|
||||
.rev()
|
||||
.fold_while(None, |style, request| match request.hitbox_id {
|
||||
None => Done(Some(request.style)),
|
||||
Some(hitbox_id) => Continue(
|
||||
style.or_else(|| hitbox_id.is_hovered(window).then_some(request.style)),
|
||||
),
|
||||
})
|
||||
.into_inner()
|
||||
}
|
||||
|
||||
pub(crate) fn hit_test(&self, position: Point<Pixels>) -> HitTest {
|
||||
|
@ -2174,7 +2175,7 @@ impl Window {
|
|||
pub fn set_cursor_style(&mut self, style: CursorStyle, hitbox: &Hitbox) {
|
||||
self.invalidator.debug_assert_paint();
|
||||
self.next_frame.cursor_styles.push(CursorStyleRequest {
|
||||
hitbox_id: hitbox.id,
|
||||
hitbox_id: Some(hitbox.id),
|
||||
style,
|
||||
});
|
||||
}
|
||||
|
@ -2185,7 +2186,10 @@ impl Window {
|
|||
/// phase of element drawing.
|
||||
pub fn set_window_cursor_style(&mut self, style: CursorStyle) {
|
||||
self.invalidator.debug_assert_paint();
|
||||
self.next_frame.window_cursor_style = Some(style);
|
||||
self.next_frame.cursor_styles.push(CursorStyleRequest {
|
||||
hitbox_id: None,
|
||||
style,
|
||||
})
|
||||
}
|
||||
|
||||
/// Sets a tooltip to be rendered for the upcoming frame. This method should only be called
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue