@@ -15,11 +15,12 @@ use smithay::{
1515 } ,
1616 } ,
1717 delegate_compositor, delegate_data_control, delegate_data_device, delegate_fractional_scale,
18- delegate_input_method_manager, delegate_keyboard_shortcuts_inhibit, delegate_layer_shell,
19- delegate_output, delegate_pointer_constraints, delegate_pointer_gestures, delegate_presentation,
20- delegate_primary_selection, delegate_relative_pointer, delegate_seat, delegate_security_context,
21- delegate_shm, delegate_tablet_manager, delegate_text_input_manager, delegate_viewporter,
22- delegate_virtual_keyboard_manager, delegate_xdg_activation, delegate_xdg_decoration, delegate_xdg_shell,
18+ delegate_input_method_manager, delegate_input_method_manager_v3, delegate_keyboard_shortcuts_inhibit,
19+ delegate_layer_shell, delegate_output, delegate_pointer_constraints, delegate_pointer_gestures,
20+ delegate_presentation, delegate_primary_selection, delegate_relative_pointer, delegate_seat,
21+ delegate_security_context, delegate_shm, delegate_tablet_manager, delegate_text_input_manager,
22+ delegate_viewporter, delegate_virtual_keyboard_manager, delegate_xdg_activation, delegate_xdg_decoration,
23+ delegate_xdg_shell,
2324 desktop:: {
2425 space:: SpaceElement ,
2526 utils:: {
@@ -53,6 +54,10 @@ use smithay::{
5354 fifo:: { FifoBarrierCachedState , FifoManagerState } ,
5455 fractional_scale:: { with_fractional_scale, FractionalScaleHandler , FractionalScaleManagerState } ,
5556 input_method:: { InputMethodHandler , InputMethodManagerState , PopupSurface } ,
57+ input_method_v3:: {
58+ self , InputMethodHandler as InputMethodHandlerV3 ,
59+ InputMethodManagerState as InputMethodManagerStateV3 , PopupSurface as PopupSurfaceV3 ,
60+ } ,
5661 keyboard_shortcuts_inhibit:: {
5762 KeyboardShortcutsInhibitHandler , KeyboardShortcutsInhibitState , KeyboardShortcutsInhibitor ,
5863 } ,
@@ -339,6 +344,64 @@ impl<BackendData: Backend> InputMethodHandler for AnvilState<BackendData> {
339344
340345delegate_input_method_manager ! ( @<BackendData : Backend + ' static > AnvilState <BackendData >) ;
341346
347+ impl < BackendData : Backend > InputMethodHandlerV3 for AnvilState < BackendData > {
348+ fn new_popup ( & mut self , surface : PopupSurfaceV3 ) {
349+ if let Err ( err) = self . popups . track_popup ( PopupKind :: from ( surface) ) {
350+ warn ! ( "Failed to track popup: {}" , err) ;
351+ }
352+ }
353+
354+ fn popup_repositioned ( & mut self , _: PopupSurfaceV3 ) { }
355+
356+ fn dismiss_popup ( & mut self , surface : PopupSurfaceV3 ) {
357+ let parent = surface. get_parent ( ) . surface . clone ( ) ;
358+ let _ = PopupManager :: dismiss_popup ( & parent, & PopupKind :: from ( surface) ) ;
359+ }
360+
361+ fn parent_geometry ( & self , parent : & WlSurface ) -> Rectangle < i32 , smithay:: utils:: Logical > {
362+ self . space
363+ . elements ( )
364+ . find_map ( |window| ( window. wl_surface ( ) . as_deref ( ) == Some ( parent) ) . then ( || window. geometry ( ) ) )
365+ . unwrap_or_default ( )
366+ }
367+
368+ fn popup_geometry (
369+ & self ,
370+ parent : & WlSurface ,
371+ cursor : & Rectangle < i32 , Logical > ,
372+ positioner : & input_method_v3:: PositionerState ,
373+ ) -> Rectangle < i32 , Logical > {
374+ let Some ( window) = self . window_for_surface ( parent) else {
375+ panic ! ( "Input method popup without parent window" ) ;
376+ } ;
377+
378+ let mut outputs_for_window = self . space . outputs_for_element ( & window) ;
379+ if outputs_for_window. is_empty ( ) {
380+ return Default :: default ( ) ;
381+ }
382+
383+ // Get a union of all outputs' geometries.
384+ let mut outputs_geo = self
385+ . space
386+ . output_geometry ( & outputs_for_window. pop ( ) . unwrap ( ) )
387+ . unwrap ( ) ;
388+ for output in outputs_for_window {
389+ outputs_geo = outputs_geo. merge ( self . space . output_geometry ( & output) . unwrap ( ) ) ;
390+ }
391+
392+ let window_geo = self . space . element_geometry ( & window) . unwrap ( ) ;
393+
394+ // The target geometry for the positioner should be relative to its parent's geometry, so
395+ // we will compute that here.
396+ let mut target = outputs_geo;
397+ target. loc -= window_geo. loc ;
398+
399+ positioner. get_geometry_from_anchor ( * cursor, target)
400+ }
401+ }
402+
403+ delegate_input_method_manager_v3 ! ( @<BackendData : Backend + ' static > AnvilState <BackendData >) ;
404+
342405impl < BackendData : Backend > KeyboardShortcutsInhibitHandler for AnvilState < BackendData > {
343406 fn keyboard_shortcuts_inhibit_state ( & mut self ) -> & mut KeyboardShortcutsInhibitState {
344407 & mut self . keyboard_shortcuts_inhibit_state
@@ -640,6 +703,7 @@ impl<BackendData: Backend + 'static> AnvilState<BackendData> {
640703 let commit_timing_manager_state = CommitTimingManagerState :: new :: < Self > ( & dh) ;
641704 TextInputManagerState :: new :: < Self > ( & dh) ;
642705 InputMethodManagerState :: new :: < Self , _ > ( & dh, |_client| true ) ;
706+ InputMethodManagerStateV3 :: new :: < Self , _ > ( & dh, |_client| true ) ;
643707 VirtualKeyboardManagerState :: new :: < Self , _ > ( & dh, |_client| true ) ;
644708 // Expose global only if backend supports relative motion events
645709 if BackendData :: HAS_RELATIVE_MOTION {
0 commit comments