paint: Propogate input event dispatch failure to Servo to resolve deadlock#43381
Conversation
There was a problem hiding this comment.
Debug log
id:22972 [components\webdriver_server\actions.rs:290:9] "Waiting.." = "Waiting.."
3:23.64 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: MouseMove(MouseMoveEvent { point: Page((400.0, 4.0)), is_compatibility_event_for_touch: false }), id: InputEventId(0) }:InputEventId(0)
3:23.64 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(0)
3:23.64 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(0)
3:23.64 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Notify InputEventId(0)
3:23.64 pid:22972 [components\webdriver_server\actions.rs:294:9] "All done." = "All done."
3:23.64 pid:22972 [components\webdriver_server\actions.rs:290:9] "Waiting.." = "Waiting.."
3:23.64 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: MouseButton(MouseButtonEvent { action: Down, button: Left, point: Page((400.0, 4.0)) }), id: InputEventId(1) }:InputEventId(1)
3:23.64 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(1)
3:23.67 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(1)
3:23.67 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Notify InputEventId(1)
3:23.67 pid:22972 [components\webdriver_server\actions.rs:294:9] "All done." = "All done."
3:23.67 pid:22972 [components\webdriver_server\actions.rs:290:9] "Waiting.." = "Waiting.."
3:23.67 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: MouseButton(MouseButtonEvent { action: Up, button: Left, point: Page((400.0, 4.0)) }), id: InputEventId(2) }:InputEventId(2)
3:23.67 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(2)
3:23.70 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(2)
3:23.70 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Notify InputEventId(2)
3:23.70 pid:22972 [components\webdriver_server\actions.rs:294:9] "All done." = "All done."
3:23.87 pid:22972 [components\webdriver_server\actions.rs:290:9] "Waiting.." = "Waiting.."
3:23.87 pid:22972 [components\webdriver_server\actions.rs:294:9] "All done." = "All done."
3:23.87 pid:22972 [components\webdriver_server\actions.rs:290:9] "Waiting.." = "Waiting.."
3:23.88 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Down, touch_id: TouchId(2), point: Page((200.0, 200.0)), cancelable: true }), id: InputEventId(3) }:InputEventId(3)
3:23.88 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(3)
3:23.88 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Down, touch_id: TouchId(3), point: Page((210.0, 210.0)), cancelable: true }), id: InputEventId(4) }:InputEventId(4)
3:23.88 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(4)
3:23.89 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(3)
3:23.89 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Notify InputEventId(3)
3:23.89 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(4)
3:23.89 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Notify InputEventId(4)
3:23.89 pid:22972 [components\webdriver_server\actions.rs:294:9] "All done." = "All done."
3:23.90 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((197.6, 197.6)), cancelable: true }), id: InputEventId(5) }:InputEventId(5)
3:23.90 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(5)
3:23.90 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(3), point: Page((230.0, 230.0)), cancelable: true }), id: InputEventId(6) }:InputEventId(6)
3:23.90 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(6)
3:23.92 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(5)
3:23.92 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] No sender for InputEventId(5)
3:23.92 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(6)
3:23.92 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] No sender for InputEventId(6)
3:23.92 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((195.05, 195.05)), cancelable: true }), id: InputEventId(7) }:InputEventId(7)
3:23.92 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(7)
3:23.94 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((192.65, 192.65)), cancelable: true }), id: InputEventId(8) }:InputEventId(8)
3:23.94 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(8)
3:23.94 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(8)
3:23.94 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] No sender for InputEventId(8)
3:23.95 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(7)
3:23.95 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] No sender for InputEventId(7)
3:23.95 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((190.1, 190.1)), cancelable: true }), id: InputEventId(9) }:InputEventId(9)
3:23.95 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(9)
3:23.95 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(9)
3:23.95 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] No sender for InputEventId(9)
3:23.97 pid:22972 [2026-03-18T06:34:02Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((187.7, 187.7)), cancelable: true }), id: InputEventId(10) }:InputEventId(10)
3:23.97 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Servoshell: InputEventId(10)
3:23.97 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] Received InputEventId(10)
3:23.97 pid:22972 [2026-03-18T06:34:02Z ERROR servoshell::running_app_state] No sender for InputEventId(10)
3:23.99 pid:22972 [2026-03-18T06:34:03Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((185.3, 185.3)), cancelable: true }), id: InputEventId(11) }:InputEventId(11)
3:23.99 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Servoshell: InputEventId(11)
3:23.99 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Received InputEventId(11)
3:23.99 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] No sender for InputEventId(11)
3:24.00 pid:22972 [2026-03-18T06:34:03Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((182.75, 182.75)), cancelable: true }), id: InputEventId(12) }:InputEventId(12)
3:24.00 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Servoshell: InputEventId(12)
3:24.00 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Received InputEventId(12)
3:24.00 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] No sender for InputEventId(12)
3:24.02 pid:22972 [2026-03-18T06:34:03Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((180.35, 180.35)), cancelable: true }), id: InputEventId(13) }:InputEventId(13)
3:24.02 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Servoshell: InputEventId(13)
3:24.02 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Received InputEventId(13)
3:24.02 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] No sender for InputEventId(13)
3:24.03 pid:22972 [2026-03-18T06:34:03Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((177.8, 177.8)), cancelable: true }), id: InputEventId(14) }:InputEventId(14)
3:24.03 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Servoshell: InputEventId(14)
3:24.03 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Received InputEventId(14)
3:24.03 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] No sender for InputEventId(14)
3:24.05 pid:22972 [2026-03-18T06:34:03Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((175.4, 175.4)), cancelable: true }), id: InputEventId(15) }:InputEventId(15)
3:24.05 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Servoshell: InputEventId(15)
3:24.05 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Received InputEventId(15)
3:24.05 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] No sender for InputEventId(15)
3:24.07 pid:22972 [2026-03-18T06:34:03Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((173.0, 173.0)), cancelable: true }), id: InputEventId(16) }:InputEventId(16)
3:24.07 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Servoshell: InputEventId(16)
3:24.07 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Received InputEventId(16)
3:24.07 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] No sender for InputEventId(16)
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((170.45, 170.45)), cancelable: true }), id: InputEventId(17) }:InputEventId(17)
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Servoshell: InputEventId(17)
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Received InputEventId(17)
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] No sender for InputEventId(17)
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Move, touch_id: TouchId(2), point: Page((170.0, 170.0)), cancelable: true }), id: InputEventId(18) }:InputEventId(18)
3:24.10 pid:22972 [components\webdriver_server\actions.rs:290:9] "Waiting.." = "Waiting.."
3:24.10 pid:22972 [components\webdriver_server\actions.rs:294:9] "All done." = "All done."
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Servoshell: InputEventId(18)
3:24.10 pid:22972 [components\webdriver_server\actions.rs:290:9] "Waiting.." = "Waiting.."
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Up, touch_id: TouchId(2), point: Page((170.0, 170.0)), cancelable: true }), id: InputEventId(19) }:InputEventId(19)
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Servoshell: InputEventId(19)
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servo::webview] Sent InputEventAndId { event: Touch(TouchEvent { event_type: Up, touch_id: TouchId(3), point: Page((230.0, 230.0)), cancelable: true }), id: InputEventId(20) }:InputEventId(20)
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Servoshell: InputEventId(20)
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Received InputEventId(18)
3:24.10 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] No sender for InputEventId(18)
3:24.15 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Received InputEventId(19)
3:24.15 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Notify InputEventId(19)
3:24.15 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Received InputEventId(20)
3:24.15 pid:22972 [2026-03-18T06:34:03Z ERROR servoshell::running_app_state] Notify InputEventId(20)
3:24.15 pid:22972 [components\webdriver_server\actions.rs:294:9] "All done." = "All done."
Will remove the debug log commit after the review.
|
The result looks promising :) |
|
Looks like it is the one that is affecting #43231 (comment). |
What a coincidence :) |
mrobinson
left a comment
There was a problem hiding this comment.
Looks like a great start, but I think we want event handling to always work in the same way no matter how the input event failed. I think you can do this by storing events that failed to send in a vector and then waking up the event loop inside the call to WebView::notify_input_event. Then during the next wakeup, for each of the stored event ids, we would report that they were handled (but not Consumed). Maybe we need a new InputEventResult.
| .notify_scroll_event(self.id(), scroll, point); | ||
| } | ||
|
|
||
| pub fn notify_input_event(&self, event: InputEvent) -> InputEventId { |
There was a problem hiding this comment.
Instead of returning a different return value, I think the thing to do here is to asynchronously call Webview::notify_input_event_handled. That will ensure that event handling always happens in the same way, which I think is important for people using the API.
There was a problem hiding this comment.
Do we leave this as a follow-up then?
There was a problem hiding this comment.
Hrm. I think we should probably not wait. I can help to implement this if you like.
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
There was a problem hiding this comment.
Emm. But we don't need to wake up the waker?
We can just handle the vector at the end of current spin?
There was a problem hiding this comment.
I will try implementing this without wake first.
There was a problem hiding this comment.
Hrm. I think the issue is that WebView::notify_input_event might be called independently of whether the Servo event loop is spinning or not. In that case the event loop will need to spin at some point in the future and the only way to guarantee that is to actually wake up the event loop.
There was a problem hiding this comment.
Make sense. I was only thinking about WebDriver, where WebView::notify_input_event is guaranteed to be called within the spin here
servo/components/servo/servo.rs
Line 193 in 479a9b6
Let's do wake then, as it might become useful in the future.
5a9ff48 to
0901b34
Compare
|
🔨 Triggering try run (#23235667423) for Linux (WPT) |
|
Test results for linux-wpt from try job (#23235667423): Flaky unexpected result (24)
Stable unexpected results that are known to be intermittent (17)
|
|
✨ Try run (#23235667423) succeeded. |
|
Let's give this a shot. |
|
🔨 Triggering try run (#23249892178) for Linux (WPT) |
|
Test results for linux-wpt from try job (#23249892178): Flaky unexpected result (31)
Stable unexpected results that are known to be intermittent (19)
|
|
✨ Try run (#23249892178) succeeded. |
|
@mrobinson Can you check again? You asked to make some change that doesn't make real difference here instead of doing in follow-up. And I did. This fixes all testdriver tests that use pinch zoom utility function. I need that to fix touch chain. New test added by Steven in another PR also needs this. |
mrobinson
left a comment
There was a problem hiding this comment.
Nice work. I would like to suggest a few minor changes:
| /// Returning `false` means this is not going to reach constellation/script, | ||
| /// and we need to directly notify Embedder that input event is handled. |
There was a problem hiding this comment.
Nit:
| /// Returning `false` means this is not going to reach constellation/script, | |
| /// and we need to directly notify Embedder that input event is handled. | |
| /// Returning `false` means this is not going to reach the Constellation, | |
| /// and we need to directly notify the embedder that input event is handled. |
There was a problem hiding this comment.
Thanks. I think this should not be plural tho :D
Constellations->Constellation
There was a problem hiding this comment.
Yes, well spotted. I've corrected the suggestion.
52769d6 to
4f487f0
Compare
7a797de to
eef45dc
Compare
| if !self | ||
| .inner() | ||
| .servo | ||
| .paint() | ||
| .notify_input_event(self.id(), event); | ||
| .notify_input_event(self.id(), event) | ||
| { | ||
| self.inner() | ||
| .servo | ||
| .add_pending_handled_input_event(PendingHandledInputEvent { | ||
| event_id, | ||
| webview_id, | ||
| }); | ||
| self.inner().servo.event_loop_waker().wake(); | ||
| } |
There was a problem hiding this comment.
Instead of calling inner() three times, do you mind putting it in an instance variable?
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
eef45dc to
0d74d10
Compare
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
0d74d10 to
2e2070c
Compare
dispatch_input_event_with_hit_testingalready returns aboolto indicate whether the dispatch failed.However, for some reason this was used nowhere. When it fails, embedder is not informed.
This is fine for embedder as right now it only handles keyboard shortcuts for headed window,
but a disaster for WebDriver as it is synchornously waiting for the feedback.
Testing: Several tests no longer CRASH.
Fixes: #43379