Merge remote-tracking branch 'origin/main' into cancel-clicks-on-drag

This commit is contained in:
Nathan Sobo
2023-12-20 15:01:10 -07:00
33 changed files with 2166 additions and 362 deletions
+30 -32
View File
@@ -2,13 +2,13 @@ use std::{
alloc,
cell::Cell,
ops::{Deref, DerefMut},
ptr::{self, NonNull},
ptr,
rc::Rc,
};
struct ArenaElement {
value: NonNull<u8>,
drop: unsafe fn(NonNull<u8>),
value: *mut u8,
drop: unsafe fn(*mut u8),
}
impl Drop for ArenaElement {
@@ -21,8 +21,9 @@ impl Drop for ArenaElement {
}
pub struct Arena {
start: NonNull<u8>,
offset: usize,
start: *mut u8,
end: *mut u8,
offset: *mut u8,
elements: Vec<ArenaElement>,
valid: Rc<Cell<bool>>,
}
@@ -31,10 +32,12 @@ impl Arena {
pub fn new(size_in_bytes: usize) -> Self {
unsafe {
let layout = alloc::Layout::from_size_align(size_in_bytes, 1).unwrap();
let ptr = alloc::alloc(layout);
let start = alloc::alloc(layout);
let end = start.add(size_in_bytes);
Self {
start: NonNull::new_unchecked(ptr),
offset: 0,
start,
end,
offset: start,
elements: Vec::new(),
valid: Rc::new(Cell::new(true)),
}
@@ -45,7 +48,7 @@ impl Arena {
self.valid.set(false);
self.valid = Rc::new(Cell::new(true));
self.elements.clear();
self.offset = 0;
self.offset = self.start;
}
#[inline(always)]
@@ -58,24 +61,28 @@ impl Arena {
ptr::write(ptr, f());
}
unsafe fn drop<T>(ptr: NonNull<u8>) {
std::ptr::drop_in_place(ptr.cast::<T>().as_ptr());
unsafe fn drop<T>(ptr: *mut u8) {
std::ptr::drop_in_place(ptr.cast::<T>());
}
unsafe {
let layout = alloc::Layout::new::<T>().pad_to_align();
let ptr = NonNull::new_unchecked(self.start.as_ptr().add(self.offset).cast::<T>());
inner_writer(ptr.as_ptr(), f);
let next_offset = self.offset.add(layout.size());
assert!(next_offset <= self.end);
let result = ArenaRef {
ptr: self.offset.cast(),
valid: self.valid.clone(),
};
inner_writer(result.ptr, f);
self.elements.push(ArenaElement {
value: ptr.cast(),
value: self.offset,
drop: drop::<T>,
});
self.offset += layout.size();
ArenaRef {
ptr,
valid: self.valid.clone(),
}
self.offset = next_offset;
result
}
}
}
@@ -87,24 +94,15 @@ impl Drop for Arena {
}
pub struct ArenaRef<T: ?Sized> {
ptr: NonNull<T>,
ptr: *mut T,
valid: Rc<Cell<bool>>,
}
impl<T: ?Sized> Clone for ArenaRef<T> {
fn clone(&self) -> Self {
Self {
ptr: self.ptr,
valid: self.valid.clone(),
}
}
}
impl<T: ?Sized> ArenaRef<T> {
#[inline(always)]
pub fn map<U: ?Sized>(mut self, f: impl FnOnce(&mut T) -> &mut U) -> ArenaRef<U> {
ArenaRef {
ptr: unsafe { NonNull::new_unchecked(f(&mut *self)) },
ptr: f(&mut self),
valid: self.valid,
}
}
@@ -123,7 +121,7 @@ impl<T: ?Sized> Deref for ArenaRef<T> {
#[inline(always)]
fn deref(&self) -> &Self::Target {
self.validate();
unsafe { self.ptr.as_ref() }
unsafe { &*self.ptr }
}
}
@@ -131,7 +129,7 @@ impl<T: ?Sized> DerefMut for ArenaRef<T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
self.validate();
unsafe { self.ptr.as_mut() }
unsafe { &mut *self.ptr }
}
}
+23 -13
View File
@@ -1105,11 +1105,14 @@ impl Interactivity {
stacking_order: cx.stacking_order().clone(),
};
if let Some(mouse_cursor) = style.mouse_cursor {
let mouse_position = &cx.mouse_position();
let hovered = interactive_bounds.visibly_contains(mouse_position, cx);
if hovered {
cx.set_cursor_style(mouse_cursor);
if !cx.has_active_drag() {
if let Some(mouse_cursor) = style.mouse_cursor {
let mouse_position = &cx.mouse_position();
let hovered =
interactive_bounds.visibly_contains(mouse_position, cx);
if hovered {
cx.set_cursor_style(mouse_cursor);
}
}
}
@@ -1334,8 +1337,8 @@ impl Interactivity {
}
let is_hovered = interactive_bounds
.visibly_contains(&event.position, cx)
&& !cx.has_active_drag()
&& has_mouse_down.borrow().is_none();
&& has_mouse_down.borrow().is_none()
&& !cx.has_active_drag();
let mut was_hovered = was_hovered.borrow_mut();
if is_hovered != was_hovered.clone() {
@@ -1420,14 +1423,14 @@ impl Interactivity {
}
}
let clicked_state = element_state
let active_state = element_state
.clicked_state
.get_or_insert_with(Default::default)
.clone();
if clicked_state.borrow().is_clicked() {
if active_state.borrow().is_clicked() {
cx.on_mouse_event(move |_: &MouseUpEvent, phase, cx| {
if phase == DispatchPhase::Capture {
*clicked_state.borrow_mut() = ElementClickedState::default();
*active_state.borrow_mut() = ElementClickedState::default();
cx.notify();
}
});
@@ -1444,7 +1447,7 @@ impl Interactivity {
let element =
interactive_bounds.visibly_contains(&down.position, cx);
if group || element {
*clicked_state.borrow_mut() =
*active_state.borrow_mut() =
ElementClickedState { group, element };
cx.notify();
}
@@ -1465,7 +1468,6 @@ impl Interactivity {
let line_height = cx.line_height();
let scroll_max = (content_size - bounds.size).max(&Size::default());
let interactive_bounds = interactive_bounds.clone();
cx.on_mouse_event(move |event: &ScrollWheelEvent, phase, cx| {
if phase == DispatchPhase::Bubble
&& interactive_bounds.visibly_contains(&event.position, cx)
@@ -1524,7 +1526,15 @@ impl Interactivity {
cx.on_action(action_type, listener)
}
f(&style, scroll_offset.unwrap_or_default(), cx)
cx.with_z_index(style.z_index.unwrap_or(0), |cx| {
if style.background.as_ref().is_some_and(|fill| {
fill.color().is_some_and(|color| !color.is_transparent())
}) {
cx.add_opaque_layer(bounds)
}
f(&style, scroll_offset.unwrap_or_default(), cx)
})
},
);
@@ -91,6 +91,14 @@ impl UniformListScrollHandle {
}
}
}
pub fn scroll_top(&self) -> Pixels {
if let Some(state) = &*self.0.borrow() {
-state.scroll_offset.borrow().y
} else {
Pixels::ZERO
}
}
}
impl Styled for UniformList {
@@ -135,6 +143,7 @@ impl Element for UniformList {
item_size.width
}
});
let height = match available_space.height {
AvailableSpace::Definite(height) => desired_height.min(height),
AvailableSpace::MinContent | AvailableSpace::MaxContent => {
+4 -1
View File
@@ -35,7 +35,6 @@ pub(crate) struct DispatchNode {
type KeyListener = ArenaRef<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>;
#[derive(Clone)]
pub(crate) struct DispatchActionListener {
pub(crate) action_type: TypeId,
pub(crate) listener: ArenaRef<dyn Fn(&dyn Any, DispatchPhase, &mut WindowContext)>,
@@ -267,6 +266,10 @@ impl DispatchTree {
&self.nodes[node_id.0]
}
pub fn node_mut(&mut self, node_id: DispatchNodeId) -> &mut DispatchNode {
&mut self.nodes[node_id.0]
}
fn active_node(&mut self) -> &mut DispatchNode {
let active_node_id = self.active_node_id();
&mut self.nodes[active_node_id.0]
+9
View File
@@ -104,6 +104,15 @@ impl SceneBuilder {
);
}
for (ix, surface) in self.surfaces.iter().enumerate() {
let z = layer_z_values[surface.order as LayerId as usize];
self.splitter.add(
surface
.bounds
.to_bsp_polygon(z, (PrimitiveKind::Surface, ix)),
);
}
// Sort all polygons, then reassign the order field of each primitive to `draw_order`
// We need primitives to be repr(C), hence the weird reuse of the order field for two different types.
for (draw_order, polygon) in self
+52 -15
View File
@@ -1572,30 +1572,43 @@ impl<'a> WindowContext<'a> {
self.propagate_event = true;
for node_id in &dispatch_path {
let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id);
if let Some(context) = node.context.clone() {
context_stack.push(context);
}
for key_listener in node.key_listeners.clone() {
let key_listeners = mem::take(&mut node.key_listeners);
for key_listener in &key_listeners {
key_listener(event, DispatchPhase::Capture, self);
if !self.propagate_event {
return;
break;
}
}
let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id);
node.key_listeners = key_listeners;
if !self.propagate_event {
return;
}
}
// Bubble phase
for node_id in dispatch_path.iter().rev() {
// Handle low level key events
let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
for key_listener in node.key_listeners.clone() {
let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id);
let key_listeners = mem::take(&mut node.key_listeners);
for key_listener in &key_listeners {
key_listener(event, DispatchPhase::Bubble, self);
if !self.propagate_event {
return;
break;
}
}
let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id);
node.key_listeners = key_listeners;
if !self.propagate_event {
return;
}
// Match keystrokes
let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
@@ -1639,38 +1652,52 @@ impl<'a> WindowContext<'a> {
// Capture phase
for node_id in &dispatch_path {
let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id);
let action_listeners = mem::take(&mut node.action_listeners);
for DispatchActionListener {
action_type,
listener,
} in node.action_listeners.clone()
} in &action_listeners
{
let any_action = action.as_any();
if action_type == any_action.type_id() {
if *action_type == any_action.type_id() {
listener(any_action, DispatchPhase::Capture, self);
if !self.propagate_event {
return;
break;
}
}
}
let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id);
node.action_listeners = action_listeners;
if !self.propagate_event {
return;
}
}
// Bubble phase
for node_id in dispatch_path.iter().rev() {
let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id);
let action_listeners = mem::take(&mut node.action_listeners);
for DispatchActionListener {
action_type,
listener,
} in node.action_listeners.clone()
} in &action_listeners
{
let any_action = action.as_any();
if action_type == any_action.type_id() {
if *action_type == any_action.type_id() {
self.propagate_event = false; // Actions stop propagation by default during the bubble phase
listener(any_action, DispatchPhase::Bubble, self);
if !self.propagate_event {
return;
break;
}
}
}
let node = self.window.rendered_frame.dispatch_tree.node_mut(*node_id);
node.action_listeners = action_listeners;
if !self.propagate_event {
return;
}
}
}
@@ -2057,9 +2084,14 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
size: self.window().viewport_size,
},
};
let new_stacking_order_id =
post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
let old_stacking_order = mem::take(&mut self.window_mut().next_frame.z_index_stack);
self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
self.window_mut().next_frame.content_mask_stack.push(mask);
let result = f(self);
self.window_mut().next_frame.content_mask_stack.pop();
self.window_mut().next_frame.z_index_stack = old_stacking_order;
result
}
@@ -2068,9 +2100,14 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
fn with_z_index<R>(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R {
let new_stacking_order_id =
post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
let old_stacking_order_id = mem::replace(
&mut self.window_mut().next_frame.z_index_stack.id,
new_stacking_order_id,
);
self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
self.window_mut().next_frame.z_index_stack.push(z_index);
let result = f(self);
self.window_mut().next_frame.z_index_stack.id = old_stacking_order_id;
self.window_mut().next_frame.z_index_stack.pop();
result
}