@@ -15,7 +15,7 @@ use std::sync::{Arc, Mutex, MutexGuard, Weak};
1515use wayland_client:: globals:: { BindError , GlobalList } ;
1616use wayland_client:: protocol:: wl_keyboard:: WlKeyboard ;
1717use wayland_client:: protocol:: wl_seat:: WlSeat ;
18- use wayland_client:: protocol:: wl_surface;
18+ use wayland_client:: protocol:: wl_surface:: WlSurface ;
1919use wayland_client:: WEnum ;
2020use wayland_client:: { Connection , Dispatch , Proxy , QueueHandle } ;
2121use wayland_protocols:: wp:: text_input:: zv3:: client:: zwp_text_input_v3:: {
@@ -25,12 +25,15 @@ use wayland_protocols::wp::text_input::zv3::client::zwp_text_input_v3::{
2525use wl_input_method:: input_method:: v1:: client as protocol;
2626
2727pub use protocol:: xx_input_method_v1:: XxInputMethodV1 ;
28+ pub use protocol:: xx_input_method_keyboard_v1:: XxInputMethodKeyboardV1 ;
2829pub use protocol:: xx_input_popup_positioner_v1:: XxInputPopupPositionerV1 ;
2930pub use protocol:: xx_input_popup_surface_v2:: XxInputPopupSurfaceV2 ;
3031
3132use protocol:: {
33+ xx_input_method_v1,
34+ xx_input_method_keyboard_v1,
3235 xx_input_method_manager_v2:: { self , XxInputMethodManagerV2 } ,
33- 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,
3437} ;
3538
3639pub use xx_input_popup_positioner_v1:: { Anchor , Gravity } ;
@@ -241,22 +244,22 @@ impl InputMethod {
241244 }
242245
243246 /// May cause a protocol error if there's a bound keyboard already.
244- pub fn keyboard_bind ( & self , keyboard : & WlKeyboard ) {
245- self . input_method . keyboard_bind ( & keyboard) ;
246- }
247-
248- /// May cause a protocol error if there's no bound keyboard.
249- pub fn keyboard_unbind ( & self ) {
250- self . input_method . keyboard_unbind ( ) ;
251- }
252-
253- /// May cause a protocol error on invalid serial.
254- pub fn keyboard_consume (
247+ pub fn keyboard_bind < D > (
255248 & self ,
256- serial : u32 ,
257- action : xx_input_method_v1:: KeyboardConsumeAction ,
258- ) {
259- self . input_method . keyboard_consume ( serial, action) ;
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+ ) )
260263 }
261264}
262265
@@ -301,6 +304,9 @@ pub struct InputMethodEventState {
301304 pub content_hint : ContentHint ,
302305 pub text_change_cause : ChangeCause ,
303306 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 > ,
304310 pub popups : HashMap < XxInputPopupSurfaceV2 , PopupState > ,
305311}
306312
@@ -312,6 +318,7 @@ impl Default for InputMethodEventState {
312318 content_purpose : ContentPurpose :: Normal ,
313319 text_change_cause : ChangeCause :: InputMethod ,
314320 active : Active :: default ( ) ,
321+ keyboards : Default :: default ( ) ,
315322 popups : Default :: default ( ) ,
316323 }
317324 }
@@ -425,7 +432,7 @@ pub struct Popup {
425432}
426433
427434impl Popup {
428- pub fn wl_surface ( & self ) -> & wl_surface :: WlSurface {
435+ pub fn wl_surface ( & self ) -> & WlSurface {
429436 self . surface . wl_surface ( )
430437 }
431438
@@ -555,6 +562,62 @@ impl PopupDataInner {
555562 }
556563}
557564
565+ #[ derive( Debug ) ]
566+ pub struct Keyboard ( XxInputMethodKeyboardV1 ) ;
567+
568+ impl Keyboard {
569+ /// May cause a protocol error if there's no bound keyboard.
570+ pub fn unbind ( & self ) {
571+ self . 0 . unbind ( ) ;
572+ }
573+
574+ /// May cause a protocol error on invalid serial.
575+ pub fn filter (
576+ & self ,
577+ serial : u32 ,
578+ action : xx_input_method_keyboard_v1:: FilterAction ,
579+ ) {
580+ self . 0 . filter ( serial, action) ;
581+ }
582+ }
583+
584+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
585+ pub struct KeyboardVersion ( pub u32 ) ;
586+
587+ impl < D > Dispatch < XxInputMethodKeyboardV1 , KeyboardData , D > for Keyboard
588+ where
589+ D : Dispatch < XxInputMethodKeyboardV1 , KeyboardData > + InputMethodHandler ,
590+ {
591+ fn event (
592+ _data : & mut D ,
593+ keyboard : & XxInputMethodKeyboardV1 ,
594+ event : xx_input_method_keyboard_v1:: Event ,
595+ data : & KeyboardData ,
596+ _conn : & Connection ,
597+ _qh : & QueueHandle < D > ,
598+ ) {
599+ if let Some ( im) = data. im . upgrade ( ) {
600+ use xx_input_method_keyboard_v1:: Event ;
601+ match event {
602+ Event :: NotifyVersion { version } => {
603+ let mut im = im. lock ( ) . unwrap ( ) ;
604+ im. pending_state . keyboards
605+ . entry ( keyboard. clone ( ) )
606+ . or_insert ( KeyboardVersion ( version) ) ;
607+ } ,
608+ _ => unreachable ! ( ) ,
609+ }
610+ } else {
611+ warn ! ( "received event for a keyboard whose input method already disappeared" ) ;
612+ } ;
613+ }
614+ }
615+
616+ #[ derive( Debug ) ]
617+ pub struct KeyboardData {
618+ im : Weak < Mutex < InputMethodDataInner > > ,
619+ }
620+
558621#[ macro_export]
559622macro_rules! delegate_input_method_v3 {
560623 ( $( @<$( $lt: tt $( : $clt: tt $( + $dlt: tt ) * ) ? ) ,+>) ? $ty: ty) => {
@@ -570,6 +633,9 @@ macro_rules! delegate_input_method_v3 {
570633 $crate:: reexports:: client:: delegate_dispatch!( $( @< $( $lt $( : $clt $( + $dlt ) * ) ? ) ,+ >) ? $ty: [
571634 $crate:: reexports:: protocols_experimental:: input_method:: v1:: client:: xx_input_popup_positioner_v1:: XxInputPopupPositionerV1 : $crate:: seat:: input_method_v3:: PositionerData
572635 ] => $crate:: seat:: input_method_v3:: PopupPositioner ) ;
636+ $crate:: reexports:: client:: delegate_dispatch!( $( @< $( $lt $( : $clt $( + $dlt ) * ) ? ) ,+ >) ? $ty: [
637+ $crate:: reexports:: protocols_experimental:: input_method:: v1:: client:: xx_input_method_keyboard_v1:: XxInputMethodKeyboardV1 : $crate:: seat:: input_method_v3:: KeyboardData
638+ ] => $crate:: seat:: input_method_v3:: Keyboard ) ;
573639 } ;
574640}
575641
@@ -753,12 +819,22 @@ mod test {
753819 > ,
754820 {
755821 }
822+
823+ fn assert_is_keyboard_delegate < T > ( )
824+ where
825+ T : wayland_client:: Dispatch <
826+ protocol:: xx_input_method_keyboard_v1:: XxInputMethodKeyboardV1 ,
827+ KeyboardData ,
828+ > ,
829+ {
830+ }
756831
757832 #[ test]
758833 fn test_valid_assignment ( ) {
759834 assert_is_manager_delegate :: < Handler > ( ) ;
760835 assert_is_delegate :: < Handler > ( ) ;
761836 assert_is_popup_delegate :: < Handler > ( ) ;
762837 assert_is_positioner_delegate :: < Handler > ( ) ;
838+ assert_is_keyboard_delegate :: < Handler > ( ) ;
763839 }
764840}
0 commit comments