Skip to main content

gtk/auto/
im_context.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{InputHints, InputPurpose, ffi};
6use glib::{
7    object::ObjectType as _,
8    prelude::*,
9    signal::{SignalHandlerId, connect_raw},
10    translate::*,
11};
12use std::boxed::Box as Box_;
13
14glib::wrapper! {
15    /// [`IMContext`][crate::IMContext] defines the interface for GTK+ input methods. An input method
16    /// is used by GTK+ text input widgets like [`Entry`][crate::Entry] to map from key events to
17    /// Unicode character strings.
18    ///
19    /// The default input method can be set programmatically via the
20    /// [`gtk-im-module`][struct@crate::Settings#gtk-im-module] GtkSettings property. Alternatively, you may set
21    /// the GTK_IM_MODULE environment variable as documented in
22    /// [Running GTK+ Applications][gtk-running].
23    ///
24    /// The [`Entry`][crate::Entry] [`im-module`][struct@crate::Entry#im-module] and [`TextView`][crate::TextView] [`im-module`][struct@crate::TextView#im-module]
25    /// properties may also be used to set input methods for specific widget
26    /// instances. For instance, a certain entry widget might be expected to contain
27    /// certain characters which would be easier to input with a certain input
28    /// method.
29    ///
30    /// An input method may consume multiple key events in sequence and finally
31    /// output the composed result. This is called preediting, and an input method
32    /// may provide feedback about this process by displaying the intermediate
33    /// composition states as preedit text. For instance, the default GTK+ input
34    /// method implements the input of arbitrary Unicode code points by holding down
35    /// the Control and Shift keys and then typing “U” followed by the hexadecimal
36    /// digits of the code point. When releasing the Control and Shift keys,
37    /// preediting ends and the character is inserted as text. Ctrl+Shift+u20AC for
38    /// example results in the € sign.
39    ///
40    /// Additional input methods can be made available for use by GTK+ widgets as
41    /// loadable modules. An input method module is a small shared library which
42    /// implements a subclass of [`IMContext`][crate::IMContext] or [`IMContextSimple`][crate::IMContextSimple] and exports
43    /// these four functions:
44    ///
45    ///
46    ///
47    /// **⚠️ The following code is in C ⚠️**
48    ///
49    /// ```C
50    /// void im_module_init(GTypeModule *module);
51    /// ```
52    /// This function should register the `GType` of the [`IMContext`][crate::IMContext] subclass which
53    /// implements the input method by means of `g_type_module_register_type()`. Note
54    /// that `g_type_register_static()` cannot be used as the type needs to be
55    /// registered dynamically.
56    ///
57    ///
58    ///
59    /// **⚠️ The following code is in C ⚠️**
60    ///
61    /// ```C
62    /// void im_module_exit(void);
63    /// ```
64    /// Here goes any cleanup code your input method might require on module unload.
65    ///
66    ///
67    ///
68    /// **⚠️ The following code is in C ⚠️**
69    ///
70    /// ```C
71    /// void im_module_list(const GtkIMContextInfo ***contexts, int *n_contexts)
72    /// {
73    ///   *contexts = info_list;
74    ///   *n_contexts = G_N_ELEMENTS (info_list);
75    /// }
76    /// ```
77    /// This function returns the list of input methods provided by the module. The
78    /// example implementation above shows a common solution and simply returns a
79    /// pointer to statically defined array of `GtkIMContextInfo` items for each
80    /// provided input method.
81    ///
82    ///
83    ///
84    /// **⚠️ The following code is in C ⚠️**
85    ///
86    /// ```C
87    /// GtkIMContext * im_module_create(const gchar *context_id);
88    /// ```
89    /// This function should return a pointer to a newly created instance of the
90    /// [`IMContext`][crate::IMContext] subclass identified by `context_id`. The context ID is the same
91    /// as specified in the `GtkIMContextInfo` array returned by `im_module_list()`.
92    ///
93    /// After a new loadable input method module has been installed on the system,
94    /// the configuration file `gtk.immodules` needs to be
95    /// regenerated by [gtk-query-immodules-3.0][gtk-query-immodules-3.0],
96    /// in order for the new input method to become available to GTK+ applications.
97    ///
98    /// This is an Abstract Base Class, you cannot instantiate it.
99    ///
100    /// ## Properties
101    ///
102    ///
103    /// #### `input-hints`
104    ///  Readable | Writable
105    ///
106    ///
107    /// #### `input-purpose`
108    ///  Readable | Writable
109    ///
110    /// ## Signals
111    ///
112    ///
113    /// #### `commit`
114    ///  The ::commit signal is emitted when a complete input sequence
115    /// has been entered by the user. This can be a single character
116    /// immediately after a key press or the final result of preediting.
117    ///
118    ///
119    ///
120    ///
121    /// #### `delete-surrounding`
122    ///  The ::delete-surrounding signal is emitted when the input method
123    /// needs to delete all or part of the context surrounding the cursor.
124    ///
125    ///
126    ///
127    ///
128    /// #### `preedit-changed`
129    ///  The ::preedit-changed signal is emitted whenever the preedit sequence
130    /// currently being entered has changed. It is also emitted at the end of
131    /// a preedit sequence, in which case
132    /// [`IMContextExt::preedit_string()`][crate::prelude::IMContextExt::preedit_string()] returns the empty string.
133    ///
134    ///
135    ///
136    ///
137    /// #### `preedit-end`
138    ///  The ::preedit-end signal is emitted when a preediting sequence
139    /// has been completed or canceled.
140    ///
141    ///
142    ///
143    ///
144    /// #### `preedit-start`
145    ///  The ::preedit-start signal is emitted when a new preediting sequence
146    /// starts.
147    ///
148    ///
149    ///
150    ///
151    /// #### `retrieve-surrounding`
152    ///  The ::retrieve-surrounding signal is emitted when the input method
153    /// requires the context surrounding the cursor. The callback should set
154    /// the input method surrounding context by calling the
155    /// [`IMContextExt::set_surrounding()`][crate::prelude::IMContextExt::set_surrounding()] method.
156    ///
157    ///
158    ///
159    /// # Implements
160    ///
161    /// [`IMContextExt`][trait@crate::prelude::IMContextExt], [`trait@glib::ObjectExt`]
162    #[doc(alias = "GtkIMContext")]
163    pub struct IMContext(Object<ffi::GtkIMContext, ffi::GtkIMContextClass>);
164
165    match fn {
166        type_ => || ffi::gtk_im_context_get_type(),
167    }
168}
169
170impl IMContext {
171    pub const NONE: Option<&'static IMContext> = None;
172}
173
174/// Trait containing all [`struct@IMContext`] methods.
175///
176/// # Implementors
177///
178/// [`IMContextSimple`][struct@crate::IMContextSimple], [`IMContext`][struct@crate::IMContext], [`IMMulticontext`][struct@crate::IMMulticontext]
179pub trait IMContextExt: IsA<IMContext> + 'static {
180    /// Asks the widget that the input context is attached to to delete
181    /// characters around the cursor position by emitting the
182    /// GtkIMContext::delete_surrounding signal. Note that `offset` and `n_chars`
183    /// are in characters not in bytes which differs from the usage other
184    /// places in [`IMContext`][crate::IMContext].
185    ///
186    /// In order to use this function, you should first call
187    /// [`surrounding()`][Self::surrounding()] to get the current context, and
188    /// call this function immediately afterwards to make sure that you
189    /// know what you are deleting. You should also account for the fact
190    /// that even if the signal was handled, the input context might not
191    /// have deleted all the characters that were requested to be deleted.
192    ///
193    /// This function is used by an input method that wants to make
194    /// subsitutions in the existing text in response to new input. It is
195    /// not useful for applications.
196    /// ## `offset`
197    /// offset from cursor position in chars;
198    ///  a negative value means start before the cursor.
199    /// ## `n_chars`
200    /// number of characters to delete.
201    ///
202    /// # Returns
203    ///
204    /// [`true`] if the signal was handled.
205    #[doc(alias = "gtk_im_context_delete_surrounding")]
206    fn delete_surrounding(&self, offset: i32, n_chars: i32) -> bool {
207        unsafe {
208            from_glib(ffi::gtk_im_context_delete_surrounding(
209                self.as_ref().to_glib_none().0,
210                offset,
211                n_chars,
212            ))
213        }
214    }
215
216    /// Allow an input method to internally handle key press and release
217    /// events. If this function returns [`true`], then no further processing
218    /// should be done for this key event.
219    /// ## `event`
220    /// the key event
221    ///
222    /// # Returns
223    ///
224    /// [`true`] if the input method handled the key event.
225    #[doc(alias = "gtk_im_context_filter_keypress")]
226    fn filter_keypress(&self, event: &gdk::EventKey) -> bool {
227        unsafe {
228            from_glib(ffi::gtk_im_context_filter_keypress(
229                self.as_ref().to_glib_none().0,
230                mut_override(event.to_glib_none().0),
231            ))
232        }
233    }
234
235    /// Notify the input method that the widget to which this
236    /// input context corresponds has gained focus. The input method
237    /// may, for example, change the displayed feedback to reflect
238    /// this change.
239    #[doc(alias = "gtk_im_context_focus_in")]
240    fn focus_in(&self) {
241        unsafe {
242            ffi::gtk_im_context_focus_in(self.as_ref().to_glib_none().0);
243        }
244    }
245
246    /// Notify the input method that the widget to which this
247    /// input context corresponds has lost focus. The input method
248    /// may, for example, change the displayed feedback or reset the contexts
249    /// state to reflect this change.
250    #[doc(alias = "gtk_im_context_focus_out")]
251    fn focus_out(&self) {
252        unsafe {
253            ffi::gtk_im_context_focus_out(self.as_ref().to_glib_none().0);
254        }
255    }
256
257    /// Retrieve the current preedit string for the input context,
258    /// and a list of attributes to apply to the string.
259    /// This string should be displayed inserted at the insertion
260    /// point.
261    ///
262    /// # Returns
263    ///
264    ///
265    /// ## `str`
266    /// location to store the retrieved
267    ///  string. The string retrieved must be freed with `g_free()`.
268    ///
269    /// ## `attrs`
270    /// location to store the retrieved
271    ///  attribute list. When you are done with this list, you
272    ///  must unreference it with `pango_attr_list_unref()`.
273    ///
274    /// ## `cursor_pos`
275    /// location to store position of cursor (in characters)
276    ///  within the preedit string.
277    #[doc(alias = "gtk_im_context_get_preedit_string")]
278    #[doc(alias = "get_preedit_string")]
279    fn preedit_string(&self) -> (glib::GString, pango::AttrList, i32) {
280        unsafe {
281            let mut str = std::ptr::null_mut();
282            let mut attrs = std::ptr::null_mut();
283            let mut cursor_pos = std::mem::MaybeUninit::uninit();
284            ffi::gtk_im_context_get_preedit_string(
285                self.as_ref().to_glib_none().0,
286                &mut str,
287                &mut attrs,
288                cursor_pos.as_mut_ptr(),
289            );
290            (
291                from_glib_full(str),
292                from_glib_full(attrs),
293                cursor_pos.assume_init(),
294            )
295        }
296    }
297
298    /// Retrieves context around the insertion point. Input methods
299    /// typically want context in order to constrain input text based on
300    /// existing text; this is important for languages such as Thai where
301    /// only some sequences of characters are allowed.
302    ///
303    /// This function is implemented by emitting the
304    /// GtkIMContext::retrieve_surrounding signal on the input method; in
305    /// response to this signal, a widget should provide as much context as
306    /// is available, up to an entire paragraph, by calling
307    /// [`set_surrounding()`][Self::set_surrounding()]. Note that there is no obligation
308    /// for a widget to respond to the ::retrieve_surrounding signal, so input
309    /// methods must be prepared to function without context.
310    ///
311    /// # Returns
312    ///
313    /// [`true`] if surrounding text was provided; in this case
314    ///  you must free the result stored in *text.
315    ///
316    /// ## `text`
317    /// location to store a UTF-8 encoded
318    ///  string of text holding context around the insertion point.
319    ///  If the function returns [`true`], then you must free the result
320    ///  stored in this location with `g_free()`.
321    ///
322    /// ## `cursor_index`
323    /// location to store byte index of the insertion
324    ///  cursor within `text`.
325    #[doc(alias = "gtk_im_context_get_surrounding")]
326    #[doc(alias = "get_surrounding")]
327    fn surrounding(&self) -> Option<(glib::GString, i32)> {
328        unsafe {
329            let mut text = std::ptr::null_mut();
330            let mut cursor_index = std::mem::MaybeUninit::uninit();
331            let ret = from_glib(ffi::gtk_im_context_get_surrounding(
332                self.as_ref().to_glib_none().0,
333                &mut text,
334                cursor_index.as_mut_ptr(),
335            ));
336            if ret {
337                Some((from_glib_full(text), cursor_index.assume_init()))
338            } else {
339                None
340            }
341        }
342    }
343
344    /// Notify the input method that a change such as a change in cursor
345    /// position has been made. This will typically cause the input
346    /// method to clear the preedit state.
347    #[doc(alias = "gtk_im_context_reset")]
348    fn reset(&self) {
349        unsafe {
350            ffi::gtk_im_context_reset(self.as_ref().to_glib_none().0);
351        }
352    }
353
354    /// Set the client window for the input context; this is the
355    /// [`gdk::Window`][crate::gdk::Window] in which the input appears. This window is
356    /// used in order to correctly position status windows, and may
357    /// also be used for purposes internal to the input method.
358    /// ## `window`
359    /// the client window. This may be [`None`] to indicate
360    ///  that the previous client window no longer exists.
361    #[doc(alias = "gtk_im_context_set_client_window")]
362    fn set_client_window(&self, window: Option<&gdk::Window>) {
363        unsafe {
364            ffi::gtk_im_context_set_client_window(
365                self.as_ref().to_glib_none().0,
366                window.to_glib_none().0,
367            );
368        }
369    }
370
371    /// Notify the input method that a change in cursor
372    /// position has been made. The location is relative to the client
373    /// window.
374    /// ## `area`
375    /// new location
376    #[doc(alias = "gtk_im_context_set_cursor_location")]
377    fn set_cursor_location(&self, area: &gdk::Rectangle) {
378        unsafe {
379            ffi::gtk_im_context_set_cursor_location(
380                self.as_ref().to_glib_none().0,
381                area.to_glib_none().0,
382            );
383        }
384    }
385
386    /// Sets surrounding context around the insertion point and preedit
387    /// string. This function is expected to be called in response to the
388    /// GtkIMContext::retrieve_surrounding signal, and will likely have no
389    /// effect if called at other times.
390    /// ## `text`
391    /// text surrounding the insertion point, as UTF-8.
392    ///  the preedit string should not be included within
393    ///  `text`.
394    /// ## `len`
395    /// the length of `text`, or -1 if `text` is nul-terminated
396    /// ## `cursor_index`
397    /// the byte index of the insertion cursor within `text`.
398    #[doc(alias = "gtk_im_context_set_surrounding")]
399    fn set_surrounding(&self, text: &str, cursor_index: i32) {
400        let len = text.len() as _;
401        unsafe {
402            ffi::gtk_im_context_set_surrounding(
403                self.as_ref().to_glib_none().0,
404                text.to_glib_none().0,
405                len,
406                cursor_index,
407            );
408        }
409    }
410
411    /// Sets whether the IM context should use the preedit string
412    /// to display feedback. If `use_preedit` is FALSE (default
413    /// is TRUE), then the IM context may use some other method to display
414    /// feedback, such as displaying it in a child of the root window.
415    /// ## `use_preedit`
416    /// whether the IM context should use the preedit string.
417    #[doc(alias = "gtk_im_context_set_use_preedit")]
418    fn set_use_preedit(&self, use_preedit: bool) {
419        unsafe {
420            ffi::gtk_im_context_set_use_preedit(
421                self.as_ref().to_glib_none().0,
422                use_preedit.into_glib(),
423            );
424        }
425    }
426
427    #[doc(alias = "input-hints")]
428    fn input_hints(&self) -> InputHints {
429        ObjectExt::property(self.as_ref(), "input-hints")
430    }
431
432    #[doc(alias = "input-hints")]
433    fn set_input_hints(&self, input_hints: InputHints) {
434        ObjectExt::set_property(self.as_ref(), "input-hints", input_hints)
435    }
436
437    #[doc(alias = "input-purpose")]
438    fn input_purpose(&self) -> InputPurpose {
439        ObjectExt::property(self.as_ref(), "input-purpose")
440    }
441
442    #[doc(alias = "input-purpose")]
443    fn set_input_purpose(&self, input_purpose: InputPurpose) {
444        ObjectExt::set_property(self.as_ref(), "input-purpose", input_purpose)
445    }
446
447    /// The ::commit signal is emitted when a complete input sequence
448    /// has been entered by the user. This can be a single character
449    /// immediately after a key press or the final result of preediting.
450    /// ## `str`
451    /// the completed character(s) entered by the user
452    #[doc(alias = "commit")]
453    fn connect_commit<F: Fn(&Self, &str) + 'static>(&self, f: F) -> SignalHandlerId {
454        unsafe extern "C" fn commit_trampoline<P: IsA<IMContext>, F: Fn(&P, &str) + 'static>(
455            this: *mut ffi::GtkIMContext,
456            str: *mut std::ffi::c_char,
457            f: glib::ffi::gpointer,
458        ) {
459            unsafe {
460                let f: &F = &*(f as *const F);
461                f(
462                    IMContext::from_glib_borrow(this).unsafe_cast_ref(),
463                    &glib::GString::from_glib_borrow(str),
464                )
465            }
466        }
467        unsafe {
468            let f: Box_<F> = Box_::new(f);
469            connect_raw(
470                self.as_ptr() as *mut _,
471                c"commit".as_ptr(),
472                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
473                    commit_trampoline::<Self, F> as *const (),
474                )),
475                Box_::into_raw(f),
476            )
477        }
478    }
479
480    /// The ::delete-surrounding signal is emitted when the input method
481    /// needs to delete all or part of the context surrounding the cursor.
482    /// ## `offset`
483    /// the character offset from the cursor position of the text
484    ///  to be deleted. A negative value indicates a position before
485    ///  the cursor.
486    /// ## `n_chars`
487    /// the number of characters to be deleted
488    ///
489    /// # Returns
490    ///
491    /// [`true`] if the signal was handled.
492    #[doc(alias = "delete-surrounding")]
493    fn connect_delete_surrounding<F: Fn(&Self, i32, i32) -> bool + 'static>(
494        &self,
495        f: F,
496    ) -> SignalHandlerId {
497        unsafe extern "C" fn delete_surrounding_trampoline<
498            P: IsA<IMContext>,
499            F: Fn(&P, i32, i32) -> bool + 'static,
500        >(
501            this: *mut ffi::GtkIMContext,
502            offset: std::ffi::c_int,
503            n_chars: std::ffi::c_int,
504            f: glib::ffi::gpointer,
505        ) -> glib::ffi::gboolean {
506            unsafe {
507                let f: &F = &*(f as *const F);
508                f(
509                    IMContext::from_glib_borrow(this).unsafe_cast_ref(),
510                    offset,
511                    n_chars,
512                )
513                .into_glib()
514            }
515        }
516        unsafe {
517            let f: Box_<F> = Box_::new(f);
518            connect_raw(
519                self.as_ptr() as *mut _,
520                c"delete-surrounding".as_ptr(),
521                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
522                    delete_surrounding_trampoline::<Self, F> as *const (),
523                )),
524                Box_::into_raw(f),
525            )
526        }
527    }
528
529    /// The ::preedit-changed signal is emitted whenever the preedit sequence
530    /// currently being entered has changed. It is also emitted at the end of
531    /// a preedit sequence, in which case
532    /// [`preedit_string()`][Self::preedit_string()] returns the empty string.
533    #[doc(alias = "preedit-changed")]
534    fn connect_preedit_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
535        unsafe extern "C" fn preedit_changed_trampoline<P: IsA<IMContext>, F: Fn(&P) + 'static>(
536            this: *mut ffi::GtkIMContext,
537            f: glib::ffi::gpointer,
538        ) {
539            unsafe {
540                let f: &F = &*(f as *const F);
541                f(IMContext::from_glib_borrow(this).unsafe_cast_ref())
542            }
543        }
544        unsafe {
545            let f: Box_<F> = Box_::new(f);
546            connect_raw(
547                self.as_ptr() as *mut _,
548                c"preedit-changed".as_ptr(),
549                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
550                    preedit_changed_trampoline::<Self, F> as *const (),
551                )),
552                Box_::into_raw(f),
553            )
554        }
555    }
556
557    /// The ::preedit-end signal is emitted when a preediting sequence
558    /// has been completed or canceled.
559    #[doc(alias = "preedit-end")]
560    fn connect_preedit_end<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
561        unsafe extern "C" fn preedit_end_trampoline<P: IsA<IMContext>, F: Fn(&P) + 'static>(
562            this: *mut ffi::GtkIMContext,
563            f: glib::ffi::gpointer,
564        ) {
565            unsafe {
566                let f: &F = &*(f as *const F);
567                f(IMContext::from_glib_borrow(this).unsafe_cast_ref())
568            }
569        }
570        unsafe {
571            let f: Box_<F> = Box_::new(f);
572            connect_raw(
573                self.as_ptr() as *mut _,
574                c"preedit-end".as_ptr(),
575                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
576                    preedit_end_trampoline::<Self, F> as *const (),
577                )),
578                Box_::into_raw(f),
579            )
580        }
581    }
582
583    /// The ::preedit-start signal is emitted when a new preediting sequence
584    /// starts.
585    #[doc(alias = "preedit-start")]
586    fn connect_preedit_start<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
587        unsafe extern "C" fn preedit_start_trampoline<P: IsA<IMContext>, F: Fn(&P) + 'static>(
588            this: *mut ffi::GtkIMContext,
589            f: glib::ffi::gpointer,
590        ) {
591            unsafe {
592                let f: &F = &*(f as *const F);
593                f(IMContext::from_glib_borrow(this).unsafe_cast_ref())
594            }
595        }
596        unsafe {
597            let f: Box_<F> = Box_::new(f);
598            connect_raw(
599                self.as_ptr() as *mut _,
600                c"preedit-start".as_ptr(),
601                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
602                    preedit_start_trampoline::<Self, F> as *const (),
603                )),
604                Box_::into_raw(f),
605            )
606        }
607    }
608
609    /// The ::retrieve-surrounding signal is emitted when the input method
610    /// requires the context surrounding the cursor. The callback should set
611    /// the input method surrounding context by calling the
612    /// [`set_surrounding()`][Self::set_surrounding()] method.
613    ///
614    /// # Returns
615    ///
616    /// [`true`] if the signal was handled.
617    #[doc(alias = "retrieve-surrounding")]
618    fn connect_retrieve_surrounding<F: Fn(&Self) -> bool + 'static>(
619        &self,
620        f: F,
621    ) -> SignalHandlerId {
622        unsafe extern "C" fn retrieve_surrounding_trampoline<
623            P: IsA<IMContext>,
624            F: Fn(&P) -> bool + 'static,
625        >(
626            this: *mut ffi::GtkIMContext,
627            f: glib::ffi::gpointer,
628        ) -> glib::ffi::gboolean {
629            unsafe {
630                let f: &F = &*(f as *const F);
631                f(IMContext::from_glib_borrow(this).unsafe_cast_ref()).into_glib()
632            }
633        }
634        unsafe {
635            let f: Box_<F> = Box_::new(f);
636            connect_raw(
637                self.as_ptr() as *mut _,
638                c"retrieve-surrounding".as_ptr(),
639                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
640                    retrieve_surrounding_trampoline::<Self, F> as *const (),
641                )),
642                Box_::into_raw(f),
643            )
644        }
645    }
646
647    #[doc(alias = "input-hints")]
648    fn connect_input_hints_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
649        unsafe extern "C" fn notify_input_hints_trampoline<
650            P: IsA<IMContext>,
651            F: Fn(&P) + 'static,
652        >(
653            this: *mut ffi::GtkIMContext,
654            _param_spec: glib::ffi::gpointer,
655            f: glib::ffi::gpointer,
656        ) {
657            unsafe {
658                let f: &F = &*(f as *const F);
659                f(IMContext::from_glib_borrow(this).unsafe_cast_ref())
660            }
661        }
662        unsafe {
663            let f: Box_<F> = Box_::new(f);
664            connect_raw(
665                self.as_ptr() as *mut _,
666                c"notify::input-hints".as_ptr(),
667                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
668                    notify_input_hints_trampoline::<Self, F> as *const (),
669                )),
670                Box_::into_raw(f),
671            )
672        }
673    }
674
675    #[doc(alias = "input-purpose")]
676    fn connect_input_purpose_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
677        unsafe extern "C" fn notify_input_purpose_trampoline<
678            P: IsA<IMContext>,
679            F: Fn(&P) + 'static,
680        >(
681            this: *mut ffi::GtkIMContext,
682            _param_spec: glib::ffi::gpointer,
683            f: glib::ffi::gpointer,
684        ) {
685            unsafe {
686                let f: &F = &*(f as *const F);
687                f(IMContext::from_glib_borrow(this).unsafe_cast_ref())
688            }
689        }
690        unsafe {
691            let f: Box_<F> = Box_::new(f);
692            connect_raw(
693                self.as_ptr() as *mut _,
694                c"notify::input-purpose".as_ptr(),
695                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
696                    notify_input_purpose_trampoline::<Self, F> as *const (),
697                )),
698                Box_::into_raw(f),
699            )
700        }
701    }
702}
703
704impl<O: IsA<IMContext>> IMContextExt for O {}