mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 13:12:46 +00:00 
			
		
		
		
	LibWeb+LibWebView: Migrate Browser's input event handling to LibWebView
The Serenity chrome is the only chrome thus far that sends all input key and mouse events to WebContent, including shortcut activations. This is necessary for all chromes - we must give web pages a chance to intercept input events before handling them ourselves. To make this easier for other chromes, this patch moves Serenity's input event handling to LibWebView. To do so, we add the Web::InputEvent type, which models the event data we need within LibWeb. Chromes will then be responsible for converting between this type and their native events. This class lives in LibWeb (rather than LibWebView) because the plan is to use it wholesale throughout the Page's event handler and across IPC. Right now, we still send the individual fields of the event over IPC, but it will be an easy refactor to send the event itself. We just can't do this until all chromes have been ported to this event queueing. Also note that we now only handle key input events back in the chrome. WebContent handles all mouse events that it possibly can. If it was not able to handle a mouse event, there's nothing for the chrome to do (i.e. there is no clicking, scrolling, etc. the chrome is able to do if the WebContent couldn't).
This commit is contained in:
		
							parent
							
								
									f2204e2b3a
								
							
						
					
					
						commit
						ea682207d0
					
				
					 7 changed files with 191 additions and 148 deletions
				
			
		|  | @ -112,6 +112,60 @@ void ViewImplementation::reset_zoom() | |||
|     update_zoom(); | ||||
| } | ||||
| 
 | ||||
| void ViewImplementation::enqueue_input_event(Web::InputEvent event) | ||||
| { | ||||
|     // Send the next event over to the WebContent to be handled by JS. We'll later get a message to say whether JS
 | ||||
|     // prevented the default event behavior, at which point we either discard or handle that event, and then try to
 | ||||
|     // process the next one.
 | ||||
|     m_pending_input_events.enqueue(move(event)); | ||||
| 
 | ||||
|     // FIXME: Replace these IPCs with a singular "async_input_event".
 | ||||
|     m_pending_input_events.tail().visit( | ||||
|         [this](Web::KeyEvent const& event) { | ||||
|             switch (event.type) { | ||||
|             case Web::KeyEvent::Type::KeyDown: | ||||
|                 client().async_key_down(m_client_state.page_index, event.key, event.modifiers, event.code_point); | ||||
|                 break; | ||||
|             case Web::KeyEvent::Type::KeyUp: | ||||
|                 client().async_key_up(m_client_state.page_index, event.key, event.modifiers, event.code_point); | ||||
|                 break; | ||||
|             } | ||||
|         }, | ||||
|         [this](Web::MouseEvent const& event) { | ||||
|             switch (event.type) { | ||||
|             case Web::MouseEvent::Type::MouseDown: | ||||
|                 client().async_mouse_down(m_client_state.page_index, event.position, event.screen_position, event.button, event.buttons, event.modifiers); | ||||
|                 break; | ||||
|             case Web::MouseEvent::Type::MouseUp: | ||||
|                 client().async_mouse_up(m_client_state.page_index, event.position, event.screen_position, event.button, event.buttons, event.modifiers); | ||||
|                 break; | ||||
|             case Web::MouseEvent::Type::MouseMove: | ||||
|                 client().async_mouse_move(m_client_state.page_index, event.position, event.screen_position, event.button, event.buttons, event.modifiers); | ||||
|                 break; | ||||
|             case Web::MouseEvent::Type::MouseWheel: | ||||
|                 client().async_mouse_wheel(m_client_state.page_index, event.position, event.screen_position, event.button, event.buttons, event.modifiers, event.wheel_delta_x, event.wheel_delta_y); | ||||
|                 break; | ||||
|             case Web::MouseEvent::Type::DoubleClick: | ||||
|                 client().async_doubleclick(m_client_state.page_index, event.position, event.screen_position, event.button, event.buttons, event.modifiers); | ||||
|                 break; | ||||
|             } | ||||
|         }); | ||||
| } | ||||
| 
 | ||||
| void ViewImplementation::did_finish_handling_input_event(Badge<WebContentClient>, bool event_was_accepted) | ||||
| { | ||||
|     auto event = m_pending_input_events.dequeue(); | ||||
| 
 | ||||
|     if (!event_was_accepted && event.has<Web::KeyEvent>()) { | ||||
|         auto const& key_event = event.get<Web::KeyEvent>(); | ||||
| 
 | ||||
|         // Here we handle events that were not consumed or cancelled by the WebContent. Propagate the event back
 | ||||
|         // to the concrete view implementation.
 | ||||
|         if (on_finish_handling_key_event) | ||||
|             on_finish_handling_key_event(key_event); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ViewImplementation::set_preferred_color_scheme(Web::CSS::PreferredColorScheme color_scheme) | ||||
| { | ||||
|     client().async_set_preferred_color_scheme(page_id(), color_scheme); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Flynn
						Timothy Flynn