Refactor the way the mouse events are processed

Have a function first called before the children, and then the main function
called after the children if they did not accept the event.  This will allow
processing the Flickable gesture properly
This commit is contained in:
Olivier Goffart 2021-02-12 16:31:06 +01:00
parent bb97fdd2a2
commit a71edafa33
5 changed files with 321 additions and 39 deletions

View file

@ -45,9 +45,10 @@ pub struct MouseEvent {
pub what: MouseEventType, pub what: MouseEventType,
} }
/// This value is returned by the input handler of a component /// This value is returned by the `input_event` function of an Item
/// to notify the run-time about how the event was handled and /// to notify the run-time about how the event was handled and
/// what the next steps are. /// what the next steps are.
/// See [`ItemVTable::input_event`].
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum InputEventResult { pub enum InputEventResult {
@ -56,21 +57,8 @@ pub enum InputEventResult {
EventAccepted, EventAccepted,
/// The event was ignored. /// The event was ignored.
EventIgnored, EventIgnored,
/* /// Same as grab, but continue forwarding the event to children.
/// If a child grab the mouse, the grabber will be stored in the item itself.
/// Only item that have grabbed storage can return this.
/// The new_grabber is a reference to a usize to store thenext grabber
TentativeGrab {
new_grabber: &'a Cell<usize>,
},
/// While we have a TentaztiveGrab
Forward {
to: usize,
},*/
/// All further mouse event need to be sent to this item or component /// All further mouse event need to be sent to this item or component
GrabMouse, GrabMouse,
/// One must send an MouseExit when the mouse leave this item
ObserveHover,
} }
impl Default for InputEventResult { impl Default for InputEventResult {
@ -79,6 +67,32 @@ impl Default for InputEventResult {
} }
} }
/// This value is returned by the `input_event_filter_before_children` function, which
/// can specify how to further process the event.
/// See [`ItemVTable::input_event_filter_before_children`].
#[repr(C)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum InputEventFilterResult {
/// The event is going to be forwarded to children, then the [`ItemVTable::input_event`]
/// function is called
ForwardEvent,
/// The event will be forwarded to the children, but the [`ItemVTable::input_event`] is not
/// going to be called for this item
ForwardAndIgnore,
/// Just like `ForwardEvent`, but even in the case the children grabs the mouse, this function
/// Will still be called for further event.
ForwardAndInterceptGrab,
/// The Event will not be forwarded to children, if a children already had the grab, the
/// grab will be cancelled with a [`MouseEventType::MouseExit`] event
Intercept,
}
impl Default for InputEventFilterResult {
fn default() -> Self {
Self::ForwardEvent
}
}
/// InternalKeyCode is used to certain keys to unicode characters, since our /// InternalKeyCode is used to certain keys to unicode characters, since our
/// public key event only exposes a string. This enum captures this mapping. /// public key event only exposes a string. This enum captures this mapping.
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
@ -238,18 +252,49 @@ pub fn process_mouse_input(
component: ComponentRc, component: ComponentRc,
mouse_event: MouseEvent, mouse_event: MouseEvent,
window: &crate::window::ComponentWindow, window: &crate::window::ComponentWindow,
mouse_input_state: MouseInputState, mut mouse_input_state: MouseInputState,
) -> MouseInputState { ) -> MouseInputState {
'grab: loop { 'grab: loop {
if !mouse_input_state.grabbed || mouse_input_state.item_stack.is_empty() { if !mouse_input_state.grabbed || mouse_input_state.item_stack.is_empty() {
break 'grab; break 'grab;
}; };
let mut event = mouse_event.clone(); let mut event = mouse_event.clone();
for it in mouse_input_state.item_stack.iter() { let mut intercept = false;
let item = if let Some(item) = it.upgrade() { item } else { break 'grab }; let mut invalid = false;
mouse_input_state.item_stack.retain(|it| {
if invalid {
return false;
}
let item = if let Some(item) = it.upgrade() {
item
} else {
invalid = true;
return false;
};
if intercept {
item.borrow().as_ref().input_event(
MouseEvent { pos: event.pos, what: MouseEventType::MouseExit },
window,
&item,
);
return false;
}
let g = item.borrow().as_ref().geometry(); let g = item.borrow().as_ref().geometry();
event.pos -= g.origin.to_vector(); event.pos -= g.origin.to_vector();
if item.borrow().as_ref().input_event_filter_before_children(event, window, &item)
== InputEventFilterResult::Intercept
{
intercept = true;
return false;
} }
true
});
if invalid {
break 'grab;
}
let grabber = mouse_input_state.item_stack.last().unwrap().upgrade().unwrap(); let grabber = mouse_input_state.item_stack.last().unwrap().upgrade().unwrap();
return match grabber.borrow().as_ref().input_event(event, window, &grabber) { return match grabber.borrow().as_ref().input_event(event, window, &grabber) {
InputEventResult::GrabMouse => mouse_input_state, InputEventResult::GrabMouse => mouse_input_state,
@ -285,16 +330,33 @@ pub fn process_mouse_input(
let geom = item.as_ref().geometry(); let geom = item.as_ref().geometry();
let geom = geom.translate(*offset); let geom = geom.translate(*offset);
let mut mouse_grabber_stack = mouse_grabber_stack.clone();
// FIXME: ideally we should add ourself to the stack only if InputEventFilterResult::ForwardAndInterceptGrab
// is used, but at the moment, we also use the mouse_grabber_stack to compute the offset
mouse_grabber_stack.push(item_rc.downgrade());
let post_visit_state = if geom.contains(mouse_event.pos) { let post_visit_state = if geom.contains(mouse_event.pos) {
let mut event2 = mouse_event.clone(); let mut event2 = mouse_event.clone();
event2.pos -= geom.origin.to_vector(); event2.pos -= geom.origin.to_vector();
match item.as_ref().input_event_filter_before_children(
event2.clone(),
window,
&item_rc,
) {
InputEventFilterResult::ForwardAndIgnore => None,
InputEventFilterResult::ForwardEvent => {
Some((event2, mouse_grabber_stack.clone(), item_rc.clone())) Some((event2, mouse_grabber_stack.clone(), item_rc.clone()))
}
InputEventFilterResult::ForwardAndInterceptGrab => {
Some((event2, mouse_grabber_stack.clone(), item_rc.clone()))
}
InputEventFilterResult::Intercept => return (ItemVisitorResult::Abort, None),
}
} else { } else {
None None
}; };
let mut mouse_grabber_stack = mouse_grabber_stack.clone();
mouse_grabber_stack.push(item_rc.downgrade());
( (
ItemVisitorResult::Continue((geom.origin.to_vector(), mouse_grabber_stack)), ItemVisitorResult::Continue((geom.origin.to_vector(), mouse_grabber_stack)),
post_visit_state, post_visit_state,
@ -307,8 +369,7 @@ pub fn process_mouse_input(
if let Some((event2, mouse_grabber_stack, item_rc)) = post_state { if let Some((event2, mouse_grabber_stack, item_rc)) = post_state {
match item.as_ref().input_event(event2, window, &item_rc) { match item.as_ref().input_event(event2, window, &item_rc) {
InputEventResult::EventAccepted => { InputEventResult::EventAccepted => {
result.item_stack = mouse_grabber_stack.clone(); result.item_stack = mouse_grabber_stack;
result.item_stack.push(item_rc.downgrade());
result.grabbed = false; result.grabbed = false;
return VisitChildrenResult::abort(item_rc.index(), 0); return VisitChildrenResult::abort(item_rc.index(), 0);
} }
@ -319,11 +380,6 @@ pub fn process_mouse_input(
result.grabbed = true; result.grabbed = true;
return VisitChildrenResult::abort(item_rc.index(), 0); return VisitChildrenResult::abort(item_rc.index(), 0);
} }
InputEventResult::ObserveHover => {
result.item_stack = mouse_grabber_stack.clone();
result.item_stack.push(item_rc.downgrade());
result.grabbed = false;
}
}; };
} }
r r

View file

@ -28,8 +28,8 @@ use crate::component::ComponentVTable;
use crate::graphics::PathDataIterator; use crate::graphics::PathDataIterator;
use crate::graphics::{Brush, Color, PathData, Rect, Size}; use crate::graphics::{Brush, Color, PathData, Rect, Size};
use crate::input::{ use crate::input::{
FocusEvent, InputEventResult, KeyEvent, KeyEventResult, KeyEventType, MouseEvent, FocusEvent, InputEventFilterResult, InputEventResult, KeyEvent, KeyEventResult, KeyEventType,
MouseEventType, MouseEvent, MouseEventType,
}; };
use crate::item_rendering::CachedRenderingData; use crate::item_rendering::CachedRenderingData;
use crate::layout::LayoutInfo; use crate::layout::LayoutInfo;
@ -80,7 +80,18 @@ pub struct ItemVTable {
pub implicit_size: pub implicit_size:
extern "C" fn(core::pin::Pin<VRef<ItemVTable>>, window: &ComponentWindow) -> Size, extern "C" fn(core::pin::Pin<VRef<ItemVTable>>, window: &ComponentWindow) -> Size,
/// input event /// Event handler for mouse and touch event. This function is called before being called on children.
/// Then, depending on the return value, it is called for the children, and their children, then
/// [`Self::input_event`] is called on the children, and finaly [`Self::input_event`] is called
/// on this item again.
pub input_event_filter_before_children: extern "C" fn(
core::pin::Pin<VRef<ItemVTable>>,
MouseEvent,
window: &ComponentWindow,
self_rc: &ItemRc,
) -> InputEventFilterResult,
/// Handle input event for mouse and touch event
pub input_event: extern "C" fn( pub input_event: extern "C" fn(
core::pin::Pin<VRef<ItemVTable>>, core::pin::Pin<VRef<ItemVTable>>,
MouseEvent, MouseEvent,
@ -189,6 +200,15 @@ impl Item for Rectangle {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_: MouseEvent, _: MouseEvent,
@ -253,6 +273,15 @@ impl Item for BorderRectangle {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_: MouseEvent, _: MouseEvent,
@ -339,20 +368,33 @@ impl Item for TouchArea {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
event: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
if !self.enabled() {
return InputEventFilterResult::ForwardAndIgnore;
}
Self::FIELD_OFFSETS.mouse_x.apply_pin(self).set(event.pos.x);
Self::FIELD_OFFSETS.mouse_y.apply_pin(self).set(event.pos.y);
Self::FIELD_OFFSETS.has_hover.apply_pin(self).set(event.what != MouseEventType::MouseExit);
InputEventFilterResult::ForwardAndInterceptGrab
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
event: MouseEvent, event: MouseEvent,
_window: &ComponentWindow, _window: &ComponentWindow,
_self_rc: &ItemRc, _self_rc: &ItemRc,
) -> InputEventResult { ) -> InputEventResult {
if event.what == MouseEventType::MouseExit {
Self::FIELD_OFFSETS.has_hover.apply_pin(self).set(false)
}
if !self.enabled() { if !self.enabled() {
return InputEventResult::EventIgnored; return InputEventResult::EventIgnored;
} }
Self::FIELD_OFFSETS.mouse_x.apply_pin(self).set(event.pos.x);
Self::FIELD_OFFSETS.mouse_y.apply_pin(self).set(event.pos.y);
Self::FIELD_OFFSETS.has_hover.apply_pin(self).set(event.what != MouseEventType::MouseExit);
let result = if matches!(event.what, MouseEventType::MouseReleased) { let result = if matches!(event.what, MouseEventType::MouseReleased) {
Self::FIELD_OFFSETS.clicked.apply_pin(self).call(&()); Self::FIELD_OFFSETS.clicked.apply_pin(self).call(&());
InputEventResult::EventAccepted InputEventResult::EventAccepted
@ -371,7 +413,7 @@ impl Item for TouchArea {
return if self.pressed() { return if self.pressed() {
InputEventResult::GrabMouse InputEventResult::GrabMouse
} else { } else {
InputEventResult::ObserveHover InputEventResult::EventAccepted
} }
} }
}); });
@ -446,6 +488,15 @@ impl Item for FocusScope {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardEvent
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
event: MouseEvent, event: MouseEvent,
@ -532,6 +583,15 @@ impl Item for Clip {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_: MouseEvent, _: MouseEvent,
@ -592,6 +652,15 @@ impl Item for Rotate {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_: MouseEvent, _: MouseEvent,
@ -673,6 +742,15 @@ impl Item for Path {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_: MouseEvent, _: MouseEvent,
@ -752,6 +830,16 @@ impl Item for Flickable {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
// TODO!
InputEventFilterResult::ForwardEvent
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
event: MouseEvent, event: MouseEvent,
@ -863,6 +951,15 @@ impl Item for Window {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_event: MouseEvent, _event: MouseEvent,
@ -926,6 +1023,15 @@ impl Item for BoxShadow {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_event: MouseEvent, _event: MouseEvent,

View file

@ -21,7 +21,9 @@ When adding an item or a property, it needs to be kept in sync with different pl
*/ */
use super::{Item, ItemConsts, ItemRc}; use super::{Item, ItemConsts, ItemRc};
use crate::graphics::{Rect, Resource, Size}; use crate::graphics::{Rect, Resource, Size};
use crate::input::{FocusEvent, InputEventResult, KeyEvent, KeyEventResult, MouseEvent}; use crate::input::{
FocusEvent, InputEventFilterResult, InputEventResult, KeyEvent, KeyEventResult, MouseEvent,
};
use crate::item_rendering::CachedRenderingData; use crate::item_rendering::CachedRenderingData;
use crate::item_rendering::ItemRenderer; use crate::item_rendering::ItemRenderer;
use crate::layout::LayoutInfo; use crate::layout::LayoutInfo;
@ -78,6 +80,15 @@ impl Item for Image {
window.0.image_size(Self::FIELD_OFFSETS.source.apply_pin(self)) window.0.image_size(Self::FIELD_OFFSETS.source.apply_pin(self))
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_: MouseEvent, _: MouseEvent,
@ -140,6 +151,15 @@ impl Item for ClippedImage {
window.0.image_size(Self::FIELD_OFFSETS.source.apply_pin(self)) window.0.image_size(Self::FIELD_OFFSETS.source.apply_pin(self))
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_: MouseEvent, _: MouseEvent,

View file

@ -22,11 +22,11 @@ When adding an item or a property, it needs to be kept in sync with different pl
use super::{Item, ItemConsts, ItemRc, VoidArg}; use super::{Item, ItemConsts, ItemRc, VoidArg};
use crate::graphics::{Brush, Color, Rect, Size}; use crate::graphics::{Brush, Color, Rect, Size};
use crate::input::InternalKeyCode;
use crate::input::{ use crate::input::{
FocusEvent, InputEventResult, KeyEvent, KeyEventResult, KeyEventType, KeyboardModifiers, FocusEvent, InputEventResult, KeyEvent, KeyEventResult, KeyEventType, KeyboardModifiers,
MouseEvent, MouseEventType, MouseEvent, MouseEventType,
}; };
use crate::input::{InputEventFilterResult, InternalKeyCode};
use crate::item_rendering::{CachedRenderingData, ItemRenderer}; use crate::item_rendering::{CachedRenderingData, ItemRenderer};
use crate::layout::LayoutInfo; use crate::layout::LayoutInfo;
#[cfg(feature = "rtti")] #[cfg(feature = "rtti")]
@ -150,6 +150,15 @@ impl Item for Text {
.unwrap_or_default() .unwrap_or_default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_: MouseEvent, _: MouseEvent,
@ -260,6 +269,15 @@ impl Item for TextInput {
.unwrap_or_default() .unwrap_or_default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardEvent
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
event: MouseEvent, event: MouseEvent,

View file

@ -29,7 +29,8 @@ use core::pin::Pin;
use cpp::cpp; use cpp::cpp;
use sixtyfps_corelib::graphics::{Rect, Size}; use sixtyfps_corelib::graphics::{Rect, Size};
use sixtyfps_corelib::input::{ use sixtyfps_corelib::input::{
FocusEvent, InputEventResult, KeyEvent, KeyEventResult, MouseEvent, MouseEventType, FocusEvent, InputEventFilterResult, InputEventResult, KeyEvent, KeyEventResult, MouseEvent,
MouseEventType,
}; };
use sixtyfps_corelib::item_rendering::{CachedRenderingData, ItemRenderer}; use sixtyfps_corelib::item_rendering::{CachedRenderingData, ItemRenderer};
use sixtyfps_corelib::items::{Item, ItemConsts, ItemRc, ItemVTable, VoidArg}; use sixtyfps_corelib::items::{Item, ItemConsts, ItemRc, ItemVTable, VoidArg};
@ -186,6 +187,15 @@ impl Item for NativeButton {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardEvent
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
event: MouseEvent, event: MouseEvent,
@ -307,6 +317,15 @@ impl Item for NativeCheckBox {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardEvent
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
event: MouseEvent, event: MouseEvent,
@ -456,6 +475,15 @@ impl Item for NativeSpinBox {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardEvent
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
event: MouseEvent, event: MouseEvent,
@ -661,6 +689,15 @@ impl Item for NativeSlider {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardEvent
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
event: MouseEvent, event: MouseEvent,
@ -906,6 +943,15 @@ impl Item for NativeGroupBox {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardEvent
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_: MouseEvent, _: MouseEvent,
@ -1050,6 +1096,15 @@ impl Item for NativeLineEdit {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_: MouseEvent, _: MouseEvent,
@ -1204,6 +1259,15 @@ impl Item for NativeScrollView {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardEvent
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
event: MouseEvent, event: MouseEvent,
@ -1523,6 +1587,15 @@ impl Item for NativeStandardListViewItem {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardAndIgnore
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
_event: MouseEvent, _event: MouseEvent,
@ -1627,6 +1700,15 @@ impl Item for NativeComboBox {
Default::default() Default::default()
} }
fn input_event_filter_before_children(
self: Pin<&Self>,
_: MouseEvent,
_window: &ComponentWindow,
_self_rc: &ItemRc,
) -> InputEventFilterResult {
InputEventFilterResult::ForwardEvent
}
fn input_event( fn input_event(
self: Pin<&Self>, self: Pin<&Self>,
event: MouseEvent, event: MouseEvent,