@@ -13,8 +13,9 @@ use std::ops::Deref;
1313use std:: sync:: { Arc , Mutex , MutexGuard , Weak } ;
1414
1515use wayland_client:: globals:: { BindError , GlobalList } ;
16+ use wayland_client:: protocol:: wl_keyboard:: WlKeyboard ;
1617use wayland_client:: protocol:: wl_seat:: WlSeat ;
17- use wayland_client:: protocol:: wl_surface;
18+ use wayland_client:: protocol:: wl_surface:: WlSurface ;
1819use wayland_client:: WEnum ;
1920use wayland_client:: { Connection , Dispatch , Proxy , QueueHandle } ;
2021use wayland_protocols:: wp:: text_input:: zv3:: client:: zwp_text_input_v3:: {
@@ -24,12 +25,15 @@ use wayland_protocols::wp::text_input::zv3::client::zwp_text_input_v3::{
2425use wl_input_method:: input_method:: v1:: client as protocol;
2526
2627pub use protocol:: xx_input_method_v1:: XxInputMethodV1 ;
28+ pub use protocol:: xx_input_method_keyboard_v1:: XxInputMethodKeyboardV1 ;
2729pub use protocol:: xx_input_popup_positioner_v1:: XxInputPopupPositionerV1 ;
2830pub use protocol:: xx_input_popup_surface_v2:: XxInputPopupSurfaceV2 ;
2931
3032use protocol:: {
33+ xx_input_method_v1,
34+ xx_input_method_keyboard_v1,
3135 xx_input_method_manager_v2:: { self , XxInputMethodManagerV2 } ,
32- xx_input_method_v1 , xx_input_popup_positioner_v1, xx_input_popup_surface_v2,
36+ xx_input_popup_positioner_v1, xx_input_popup_surface_v2,
3337} ;
3438
3539pub use xx_input_popup_positioner_v1:: { Anchor , Gravity } ;
@@ -59,7 +63,7 @@ impl InputMethodManager {
5963 where
6064 D : Dispatch < XxInputMethodManagerV2 , GlobalData > + ' static ,
6165 {
62- let manager = globals. bind ( qh, 2 ..=2 , GlobalData ) ?;
66+ let manager = globals. bind ( qh, 3 ..=3 , GlobalData ) ?;
6367 Ok ( Self { manager } )
6468 }
6569
@@ -238,6 +242,25 @@ impl InputMethod {
238242 surface,
239243 }
240244 }
245+
246+ /// May cause a protocol error if there's a bound keyboard already.
247+ pub fn keyboard_bind < D > (
248+ & self ,
249+ qh : & QueueHandle < D > ,
250+ keyboard : & WlKeyboard ,
251+ surface : & WlSurface ,
252+ ) -> Keyboard
253+ where
254+ D : Dispatch < XxInputMethodKeyboardV1 , KeyboardData > + ' static ,
255+ {
256+ let data = self . input_method . data :: < InputMethodData > ( ) . unwrap ( ) ;
257+ Keyboard ( self . input_method . keyboard_bind (
258+ keyboard,
259+ surface,
260+ qh,
261+ KeyboardData { im : Arc :: downgrade ( & data. inner ) } ,
262+ ) )
263+ }
241264}
242265
243266#[ derive( Debug ) ]
@@ -281,6 +304,9 @@ pub struct InputMethodEventState {
281304 pub content_hint : ContentHint ,
282305 pub text_change_cause : ChangeCause ,
283306 pub active : Active ,
307+ /// A hash map of keyboards which reported a version.
308+ /// A missing entry is equal to version 0, meaning inactive.
309+ pub keyboards : HashMap < XxInputMethodKeyboardV1 , KeyboardVersion > ,
284310 pub popups : HashMap < XxInputPopupSurfaceV2 , PopupState > ,
285311}
286312
@@ -292,6 +318,7 @@ impl Default for InputMethodEventState {
292318 content_purpose : ContentPurpose :: Normal ,
293319 text_change_cause : ChangeCause :: InputMethod ,
294320 active : Active :: default ( ) ,
321+ keyboards : Default :: default ( ) ,
295322 popups : Default :: default ( ) ,
296323 }
297324 }
@@ -406,7 +433,7 @@ pub struct Popup {
406433}
407434
408435impl Popup {
409- pub fn wl_surface ( & self ) -> & wl_surface :: WlSurface {
436+ pub fn wl_surface ( & self ) -> & WlSurface {
410437 self . surface . wl_surface ( )
411438 }
412439
@@ -536,6 +563,62 @@ impl PopupDataInner {
536563 }
537564}
538565
566+ #[ derive( Debug ) ]
567+ pub struct Keyboard ( XxInputMethodKeyboardV1 ) ;
568+
569+ impl Keyboard {
570+ /// May cause a protocol error if there's no bound keyboard.
571+ pub fn unbind ( & self ) {
572+ self . 0 . unbind ( ) ;
573+ }
574+
575+ /// May cause a protocol error on invalid serial.
576+ pub fn filter (
577+ & self ,
578+ serial : u32 ,
579+ action : xx_input_method_keyboard_v1:: FilterAction ,
580+ ) {
581+ self . 0 . filter ( serial, action) ;
582+ }
583+ }
584+
585+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
586+ pub struct KeyboardVersion ( pub u32 ) ;
587+
588+ impl < D > Dispatch < XxInputMethodKeyboardV1 , KeyboardData , D > for Keyboard
589+ where
590+ D : Dispatch < XxInputMethodKeyboardV1 , KeyboardData > + InputMethodHandler ,
591+ {
592+ fn event (
593+ _data : & mut D ,
594+ keyboard : & XxInputMethodKeyboardV1 ,
595+ event : xx_input_method_keyboard_v1:: Event ,
596+ data : & KeyboardData ,
597+ _conn : & Connection ,
598+ _qh : & QueueHandle < D > ,
599+ ) {
600+ if let Some ( im) = data. im . upgrade ( ) {
601+ use xx_input_method_keyboard_v1:: Event ;
602+ match event {
603+ Event :: NotifyVersion { version } => {
604+ let mut im = im. lock ( ) . unwrap ( ) ;
605+ im. pending_state . keyboards
606+ . entry ( keyboard. clone ( ) )
607+ . or_insert ( KeyboardVersion ( version) ) ;
608+ } ,
609+ _ => unreachable ! ( ) ,
610+ }
611+ } else {
612+ warn ! ( "received event for a keyboard whose input method already disappeared" ) ;
613+ } ;
614+ }
615+ }
616+
617+ #[ derive( Debug ) ]
618+ pub struct KeyboardData {
619+ im : Weak < Mutex < InputMethodDataInner > > ,
620+ }
621+
539622#[ macro_export]
540623macro_rules! delegate_input_method_v3 {
541624 ( $( @<$( $lt: tt $( : $clt: tt $( + $dlt: tt ) * ) ? ) ,+>) ? $ty: ty) => {
@@ -551,6 +634,9 @@ macro_rules! delegate_input_method_v3 {
551634 $crate:: reexports:: client:: delegate_dispatch!( $( @< $( $lt $( : $clt $( + $dlt ) * ) ? ) ,+ >) ? $ty: [
552635 $crate:: reexports:: protocols_experimental:: input_method:: v1:: client:: xx_input_popup_positioner_v1:: XxInputPopupPositionerV1 : $crate:: seat:: input_method_v3:: PositionerData
553636 ] => $crate:: seat:: input_method_v3:: PopupPositioner ) ;
637+ $crate:: reexports:: client:: delegate_dispatch!( $( @< $( $lt $( : $clt $( + $dlt ) * ) ? ) ,+ >) ? $ty: [
638+ $crate:: reexports:: protocols_experimental:: input_method:: v1:: client:: xx_input_method_keyboard_v1:: XxInputMethodKeyboardV1 : $crate:: seat:: input_method_v3:: KeyboardData
639+ ] => $crate:: seat:: input_method_v3:: Keyboard ) ;
554640 } ;
555641}
556642
@@ -734,12 +820,22 @@ mod test {
734820 > ,
735821 {
736822 }
823+
824+ fn assert_is_keyboard_delegate < T > ( )
825+ where
826+ T : wayland_client:: Dispatch <
827+ protocol:: xx_input_method_keyboard_v1:: XxInputMethodKeyboardV1 ,
828+ KeyboardData ,
829+ > ,
830+ {
831+ }
737832
738833 #[ test]
739834 fn test_valid_assignment ( ) {
740835 assert_is_manager_delegate :: < Handler > ( ) ;
741836 assert_is_delegate :: < Handler > ( ) ;
742837 assert_is_popup_delegate :: < Handler > ( ) ;
743838 assert_is_positioner_delegate :: < Handler > ( ) ;
839+ assert_is_keyboard_delegate :: < Handler > ( ) ;
744840 }
745841}
0 commit comments