@@ -5453,72 +5453,38 @@ void InputDispatcher::setInputWindowsLocked(
54535453 onFocusChangedLocked (*changes, traceContext.getTracker (), removedFocusedWindowHandle);
54545454 }
54555455
5456- if (const auto & it = mTouchStates .mTouchStatesByDisplay .find (displayId);
5457- it != mTouchStates .mTouchStatesByDisplay .end ()) {
5458- TouchState& state = it->second ;
5459- for (size_t i = 0 ; i < state.windows .size ();) {
5460- TouchedWindow& touchedWindow = state.windows [i];
5461- if (mWindowInfos .isWindowPresent (touchedWindow.windowHandle )) {
5462- i++;
5463- continue ;
5464- }
5465- LOG (INFO) << " Touched window was removed: " << touchedWindow.windowHandle ->getName ()
5466- << " in display %" << displayId;
5467- CancelationOptions options (CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5468- " touched window was removed" , traceContext.getTracker ());
5469- synthesizeCancelationEventsForWindowLocked (touchedWindow.windowHandle , options);
5470- // Since we are about to drop the touch, cancel the events for the wallpaper as
5471- // well.
5472- if (touchedWindow.targetFlags .test (InputTarget::Flags::FOREGROUND) &&
5473- touchedWindow.windowHandle ->getInfo ()->inputConfig .test (
5474- gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
5475- for (const DeviceId deviceId : touchedWindow.getTouchingDeviceIds ()) {
5476- if (const auto & ww = state.getWallpaperWindow (deviceId); ww != nullptr ) {
5477- options.deviceId = deviceId;
5478- synthesizeCancelationEventsForWindowLocked (ww, options);
5479- }
5480- }
5481- }
5482- state.windows .erase (state.windows .begin () + i);
5483- }
5484-
5485- // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
5486- // could just clear the state here.
5487- if (mDragState && mDragState ->dragWindow ->getInfo ()->displayId == displayId &&
5488- std::find (windowHandles.begin (), windowHandles.end (), mDragState ->dragWindow ) ==
5489- windowHandles.end ()) {
5490- ALOGI (" Drag window went away: %s" , mDragState ->dragWindow ->getName ().c_str ());
5491- sendDropWindowCommandLocked (nullptr , 0 , 0 );
5492- mDragState .reset ();
5456+ CancelationOptions pointerCancellationOptions (CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5457+ " touched window was removed" ,
5458+ traceContext.getTracker ());
5459+ CancelationOptions hoverCancellationOptions (CancelationOptions::Mode::CANCEL_HOVER_EVENTS,
5460+ " WindowInfo changed" , traceContext.getTracker ());
5461+ const std::list<DispatcherTouchState::CancellationArgs> cancellations =
5462+ mTouchStates .updateFromWindowInfo (displayId, mWindowInfos );
5463+ for (const auto & cancellationArgs : cancellations) {
5464+ switch (cancellationArgs.mode ) {
5465+ case CancelationOptions::Mode::CANCEL_POINTER_EVENTS:
5466+ pointerCancellationOptions.deviceId = cancellationArgs.deviceId ;
5467+ synthesizeCancelationEventsForWindowLocked (cancellationArgs.windowHandle ,
5468+ pointerCancellationOptions);
5469+ break ;
5470+ case CancelationOptions::Mode::CANCEL_HOVER_EVENTS:
5471+ hoverCancellationOptions.deviceId = cancellationArgs.deviceId ;
5472+ synthesizeCancelationEventsForWindowLocked (cancellationArgs.windowHandle ,
5473+ hoverCancellationOptions);
5474+ break ;
5475+ default :
5476+ LOG_ALWAYS_FATAL (" Unexpected cancellation Mode" );
54935477 }
54945478 }
54955479
5496- // Check if the hovering should stop because the window is no longer eligible to receive it
5497- // (for example, if the touchable region changed)
5498- if (const auto & it = mTouchStates .mTouchStatesByDisplay .find (displayId);
5499- it != mTouchStates .mTouchStatesByDisplay .end ()) {
5500- TouchState& state = it->second ;
5501- for (TouchedWindow& touchedWindow : state.windows ) {
5502- std::vector<DeviceId> erasedDevices = touchedWindow.eraseHoveringPointersIf (
5503- [this , displayId, &touchedWindow](const PointerProperties& properties, float x,
5504- float y) REQUIRES (mLock ) {
5505- const bool isStylus = properties.toolType == ToolType::STYLUS;
5506- const ui::Transform displayTransform =
5507- mWindowInfos .getDisplayTransform (displayId);
5508- const bool stillAcceptsTouch =
5509- windowAcceptsTouchAt (*touchedWindow.windowHandle ->getInfo (),
5510- displayId, x, y, isStylus, displayTransform);
5511- return !stillAcceptsTouch;
5512- });
5513-
5514- for (DeviceId deviceId : erasedDevices) {
5515- CancelationOptions options (CancelationOptions::Mode::CANCEL_HOVER_EVENTS,
5516- " WindowInfo changed" ,
5517- traceContext.getTracker ());
5518- options.deviceId = deviceId;
5519- synthesizeCancelationEventsForWindowLocked (touchedWindow.windowHandle , options);
5520- }
5521- }
5480+ // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
5481+ // could just clear the state here.
5482+ if (mDragState && mDragState ->dragWindow ->getInfo ()->displayId == displayId &&
5483+ std::find (windowHandles.begin (), windowHandles.end (), mDragState ->dragWindow ) ==
5484+ windowHandles.end ()) {
5485+ ALOGI (" Drag window went away: %s" , mDragState ->dragWindow ->getName ().c_str ());
5486+ sendDropWindowCommandLocked (nullptr , 0 , 0 );
5487+ mDragState .reset ();
55225488 }
55235489
55245490 // Release information for windows that are no longer present.
@@ -5535,6 +5501,76 @@ void InputDispatcher::setInputWindowsLocked(
55355501 }
55365502}
55375503
5504+ std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>
5505+ InputDispatcher::DispatcherTouchState::updateFromWindowInfo (
5506+ ui::LogicalDisplayId displayId, const DispatcherWindowInfo& windowInfos) {
5507+ std::list<CancellationArgs> cancellations;
5508+ if (const auto & it = mTouchStatesByDisplay .find (displayId); it != mTouchStatesByDisplay .end ()) {
5509+ TouchState& state = it->second ;
5510+ cancellations = eraseRemovedWindowsFromWindowInfo (state, displayId, windowInfos);
5511+ cancellations.splice (cancellations.end (),
5512+ updateHoveringStateFromWindowInfo (state, displayId, windowInfos));
5513+ }
5514+ return cancellations;
5515+ }
5516+
5517+ std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>
5518+ InputDispatcher::DispatcherTouchState::eraseRemovedWindowsFromWindowInfo (
5519+ TouchState& state, ui::LogicalDisplayId displayId,
5520+ const DispatcherWindowInfo& windowInfos) {
5521+ std::list<CancellationArgs> cancellations;
5522+ for (auto it = state.windows .begin (); it != state.windows .end ();) {
5523+ TouchedWindow& touchedWindow = *it;
5524+ if (windowInfos.isWindowPresent (touchedWindow.windowHandle )) {
5525+ it++;
5526+ continue ;
5527+ }
5528+ LOG (INFO) << " Touched window was removed: " << touchedWindow.windowHandle ->getName ()
5529+ << " in display %" << displayId;
5530+ cancellations.emplace_back (touchedWindow.windowHandle ,
5531+ CancelationOptions::Mode::CANCEL_POINTER_EVENTS, std::nullopt );
5532+ // Since we are about to drop the touch, cancel the events for the wallpaper as well.
5533+ if (touchedWindow.targetFlags .test (InputTarget::Flags::FOREGROUND) &&
5534+ touchedWindow.windowHandle ->getInfo ()->inputConfig .test (
5535+ gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
5536+ for (const DeviceId deviceId : touchedWindow.getTouchingDeviceIds ()) {
5537+ if (const auto & ww = state.getWallpaperWindow (deviceId); ww != nullptr ) {
5538+ cancellations.emplace_back (ww, CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5539+ deviceId);
5540+ }
5541+ }
5542+ }
5543+ it = state.windows .erase (it);
5544+ }
5545+ return cancellations;
5546+ }
5547+
5548+ std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>
5549+ InputDispatcher::DispatcherTouchState::updateHoveringStateFromWindowInfo (
5550+ TouchState& state, ui::LogicalDisplayId displayId,
5551+ const DispatcherWindowInfo& windowInfos) {
5552+ std::list<CancellationArgs> cancellations;
5553+ // Check if the hovering should stop because the window is no longer eligible to receive it
5554+ // (for example, if the touchable region changed)
5555+ ui::Transform displayTransform = windowInfos.getDisplayTransform (displayId);
5556+ for (TouchedWindow& touchedWindow : state.windows ) {
5557+ std::vector<DeviceId> erasedDevices = touchedWindow.eraseHoveringPointersIf (
5558+ [&](const PointerProperties& properties, float x, float y) {
5559+ const bool isStylus = properties.toolType == ToolType::STYLUS;
5560+ const bool stillAcceptsTouch =
5561+ windowAcceptsTouchAt (*touchedWindow.windowHandle ->getInfo (), displayId,
5562+ x, y, isStylus, displayTransform);
5563+ return !stillAcceptsTouch;
5564+ });
5565+
5566+ for (DeviceId deviceId : erasedDevices) {
5567+ cancellations.emplace_back (touchedWindow.windowHandle ,
5568+ CancelationOptions::Mode::CANCEL_HOVER_EVENTS, deviceId);
5569+ }
5570+ }
5571+ return cancellations;
5572+ }
5573+
55385574void InputDispatcher::setFocusedApplication (
55395575 ui::LogicalDisplayId displayId,
55405576 const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
0 commit comments