gtk4/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#![allow(deprecated)]
5
6use crate::{ffi, InputHints, InputPurpose, Widget};
7use glib::{
8    object::ObjectType as _,
9    prelude::*,
10    signal::{connect_raw, SignalHandlerId},
11    translate::*,
12};
13use std::boxed::Box as Box_;
14
15glib::wrapper! {
16    /// The interface for GTK input methods.
17    ///
18    /// [`IMContext`][crate::IMContext] is used by GTK text input widgets like [`Text`][crate::Text]
19    /// to map from key events to Unicode character strings.
20    ///
21    /// An input method may consume multiple key events in sequence before finally
22    /// outputting the composed result. This is called *preediting*, and an input
23    /// method may provide feedback about this process by displaying the intermediate
24    /// composition states as preedit text. To do so, the [`IMContext`][crate::IMContext] will emit
25    /// [`preedit-start`][struct@crate::IMContext#preedit-start], [`preedit-changed`][struct@crate::IMContext#preedit-changed]
26    /// and [`preedit-end`][struct@crate::IMContext#preedit-end] signals.
27    ///
28    /// For instance, the built-in GTK input method [`IMContextSimple`][crate::IMContextSimple]
29    /// implements the input of arbitrary Unicode code points by holding down the
30    /// <kbd>Control</kbd> and <kbd>Shift</kbd> keys and then typing <kbd>u</kbd>
31    /// followed by the hexadecimal digits of the code point. When releasing the
32    /// <kbd>Control</kbd> and <kbd>Shift</kbd> keys, preediting ends and the
33    /// character is inserted as text. For example,
34    ///
35    ///     Ctrl+Shift+u 2 0 A C
36    ///
37    /// results in the € sign.
38    ///
39    /// Additional input methods can be made available for use by GTK widgets as
40    /// loadable modules. An input method module is a small shared library which
41    /// provides a `GIOExtension` for the extension point named "gtk-im-module".
42    ///
43    /// To connect a widget to the users preferred input method, you should use
44    /// [`IMMulticontext`][crate::IMMulticontext].
45    ///
46    /// This is an Abstract Base Class, you cannot instantiate it.
47    ///
48    /// ## Properties
49    ///
50    ///
51    /// #### `input-hints`
52    ///  Additional hints that allow input methods to fine-tune
53    /// their behaviour.
54    ///
55    /// Readable | Writeable
56    ///
57    ///
58    /// #### `input-purpose`
59    ///  The purpose of the text field that the `GtkIMContext is connected to.
60    ///
61    /// This property can be used by on-screen keyboards and other input
62    /// methods to adjust their behaviour.
63    ///
64    /// Readable | Writeable
65    ///
66    /// ## Signals
67    ///
68    ///
69    /// #### `commit`
70    ///  The ::commit signal is emitted when a complete input sequence
71    /// has been entered by the user.
72    ///
73    /// If the commit comes after a preediting sequence, the
74    /// ::commit signal is emitted after ::preedit-end.
75    ///
76    /// This can be a single character immediately after a key press or
77    /// the final result of preediting.
78    ///
79    ///
80    ///
81    ///
82    /// #### `delete-surrounding`
83    ///  The ::delete-surrounding signal is emitted when the input method
84    /// needs to delete all or part of the context surrounding the cursor.
85    ///
86    ///
87    ///
88    ///
89    /// #### `invalid-composition`
90    ///  Emitted when the filtered keys do not compose to a single valid character.
91    ///
92    ///
93    ///
94    ///
95    /// #### `preedit-changed`
96    ///  The ::preedit-changed signal is emitted whenever the preedit sequence
97    /// currently being entered has changed.
98    ///
99    /// It is also emitted at the end of a preedit sequence, in which case
100    /// [`IMContextExt::preedit_string()`][crate::prelude::IMContextExt::preedit_string()] returns the empty string.
101    ///
102    ///
103    ///
104    ///
105    /// #### `preedit-end`
106    ///  The ::preedit-end signal is emitted when a preediting sequence
107    /// has been completed or canceled.
108    ///
109    ///
110    ///
111    ///
112    /// #### `preedit-start`
113    ///  The ::preedit-start signal is emitted when a new preediting sequence
114    /// starts.
115    ///
116    ///
117    ///
118    ///
119    /// #### `retrieve-surrounding`
120    ///  The ::retrieve-surrounding signal is emitted when the input method
121    /// requires the context surrounding the cursor.
122    ///
123    /// The callback should set the input method surrounding context by
124    /// calling the [`IMContextExt::set_surrounding()`][crate::prelude::IMContextExt::set_surrounding()] method.
125    ///
126    ///
127    ///
128    /// # Implements
129    ///
130    /// [`IMContextExt`][trait@crate::prelude::IMContextExt], [`trait@glib::ObjectExt`]
131    #[doc(alias = "GtkIMContext")]
132    pub struct IMContext(Object<ffi::GtkIMContext, ffi::GtkIMContextClass>);
133
134    match fn {
135        type_ => || ffi::gtk_im_context_get_type(),
136    }
137}
138
139impl IMContext {
140    pub const NONE: Option<&'static IMContext> = None;
141}
142
143/// Trait containing all [`struct@IMContext`] methods.
144///
145/// # Implementors
146///
147/// [`IMContextSimple`][struct@crate::IMContextSimple], [`IMContext`][struct@crate::IMContext], [`IMMulticontext`][struct@crate::IMMulticontext]
148pub trait IMContextExt: IsA<IMContext> + 'static {
149    /// Requests the platform to show an on-screen keyboard for user input.
150    ///
151    /// This method will return [`true`] if this request was actually performed
152    /// to the platform, other environmental factors may result in an on-screen
153    /// keyboard effectively not showing up.
154    /// ## `event`
155    /// a [`gdk::Event`][crate::gdk::Event]
156    ///
157    /// # Returns
158    ///
159    /// [`true`] if an on-screen keyboard could be requested to the platform.
160    #[cfg(feature = "v4_14")]
161    #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
162    #[doc(alias = "gtk_im_context_activate_osk")]
163    fn activate_osk(&self, event: Option<impl AsRef<gdk::Event>>) -> bool {
164        unsafe {
165            from_glib(ffi::gtk_im_context_activate_osk(
166                self.as_ref().to_glib_none().0,
167                event.as_ref().map(|p| p.as_ref()).to_glib_none().0,
168            ))
169        }
170    }
171
172    /// Asks the widget that the input context is attached to delete
173    /// characters around the cursor position by emitting the
174    /// `::delete_surrounding` signal.
175    ///
176    /// Note that @offset and @n_chars are in characters not in bytes
177    /// which differs from the usage other places in [`IMContext`][crate::IMContext].
178    ///
179    /// In order to use this function, you should first call
180    /// [`surrounding()`][Self::surrounding()] to get the current context,
181    /// and call this function immediately afterwards to make sure that you
182    /// know what you are deleting. You should also account for the fact
183    /// that even if the signal was handled, the input context might not
184    /// have deleted all the characters that were requested to be deleted.
185    ///
186    /// This function is used by an input method that wants to make
187    /// substitutions in the existing text in response to new input.
188    /// It is not useful for applications.
189    /// ## `offset`
190    /// offset from cursor position in chars;
191    ///    a negative value means start before the cursor.
192    /// ## `n_chars`
193    /// number of characters to delete.
194    ///
195    /// # Returns
196    ///
197    /// [`true`] if the signal was handled.
198    #[doc(alias = "gtk_im_context_delete_surrounding")]
199    fn delete_surrounding(&self, offset: i32, n_chars: i32) -> bool {
200        unsafe {
201            from_glib(ffi::gtk_im_context_delete_surrounding(
202                self.as_ref().to_glib_none().0,
203                offset,
204                n_chars,
205            ))
206        }
207    }
208
209    /// Allow an input method to forward key press and release events
210    /// to another input method without necessarily having a [`gdk::Event`][crate::gdk::Event]
211    /// available.
212    /// ## `press`
213    /// whether to forward a key press or release event
214    /// ## `surface`
215    /// the surface the event is for
216    /// ## `device`
217    /// the device that the event is for
218    /// ## `time`
219    /// the timestamp for the event
220    /// ## `keycode`
221    /// the keycode for the event
222    /// ## `state`
223    /// modifier state for the event
224    /// ## `group`
225    /// the active keyboard group for the event
226    ///
227    /// # Returns
228    ///
229    /// [`true`] if the input method handled the key event.
230    #[doc(alias = "gtk_im_context_filter_key")]
231    fn filter_key(
232        &self,
233        press: bool,
234        surface: &impl IsA<gdk::Surface>,
235        device: &gdk::Device,
236        time: u32,
237        keycode: u32,
238        state: gdk::ModifierType,
239        group: i32,
240    ) -> bool {
241        unsafe {
242            from_glib(ffi::gtk_im_context_filter_key(
243                self.as_ref().to_glib_none().0,
244                press.into_glib(),
245                surface.as_ref().to_glib_none().0,
246                device.to_glib_none().0,
247                time,
248                keycode,
249                state.into_glib(),
250                group,
251            ))
252        }
253    }
254
255    /// Allow an input method to internally handle key press and release
256    /// events.
257    ///
258    /// If this function returns [`true`], then no further processing
259    /// should be done for this key event.
260    /// ## `event`
261    /// the key event
262    ///
263    /// # Returns
264    ///
265    /// [`true`] if the input method handled the key event.
266    #[doc(alias = "gtk_im_context_filter_keypress")]
267    fn filter_keypress(&self, event: impl AsRef<gdk::Event>) -> bool {
268        unsafe {
269            from_glib(ffi::gtk_im_context_filter_keypress(
270                self.as_ref().to_glib_none().0,
271                event.as_ref().to_glib_none().0,
272            ))
273        }
274    }
275
276    /// Notify the input method that the widget to which this
277    /// input context corresponds has gained focus.
278    ///
279    /// The input method may, for example, change the displayed
280    /// feedback to reflect this change.
281    #[doc(alias = "gtk_im_context_focus_in")]
282    fn focus_in(&self) {
283        unsafe {
284            ffi::gtk_im_context_focus_in(self.as_ref().to_glib_none().0);
285        }
286    }
287
288    /// Notify the input method that the widget to which this
289    /// input context corresponds has lost focus.
290    ///
291    /// The input method may, for example, change the displayed
292    /// feedback or reset the contexts state to reflect this change.
293    #[doc(alias = "gtk_im_context_focus_out")]
294    fn focus_out(&self) {
295        unsafe {
296            ffi::gtk_im_context_focus_out(self.as_ref().to_glib_none().0);
297        }
298    }
299
300    /// Retrieve the current preedit string for the input context,
301    /// and a list of attributes to apply to the string.
302    ///
303    /// This string should be displayed inserted at the insertion point.
304    ///
305    /// # Returns
306    ///
307    ///
308    /// ## `str`
309    /// location to store the retrieved
310    ///   string. The string retrieved must be freed with g_free().
311    ///
312    /// ## `attrs`
313    /// location to store the retrieved
314    ///   attribute list. When you are done with this list, you
315    ///   must unreference it with `Pango::AttrList::unref()`.
316    ///
317    /// ## `cursor_pos`
318    /// location to store position of cursor
319    ///   (in characters) within the preedit string.
320    #[doc(alias = "gtk_im_context_get_preedit_string")]
321    #[doc(alias = "get_preedit_string")]
322    fn preedit_string(&self) -> (glib::GString, pango::AttrList, i32) {
323        unsafe {
324            let mut str = std::ptr::null_mut();
325            let mut attrs = std::ptr::null_mut();
326            let mut cursor_pos = std::mem::MaybeUninit::uninit();
327            ffi::gtk_im_context_get_preedit_string(
328                self.as_ref().to_glib_none().0,
329                &mut str,
330                &mut attrs,
331                cursor_pos.as_mut_ptr(),
332            );
333            (
334                from_glib_full(str),
335                from_glib_full(attrs),
336                cursor_pos.assume_init(),
337            )
338        }
339    }
340
341    /// Retrieves context around the insertion point.
342    ///
343    /// Input methods typically want context in order to constrain input text
344    /// based on existing text; this is important for languages such as Thai
345    /// where only some sequences of characters are allowed.
346    ///
347    /// This function is implemented by emitting the
348    /// [`retrieve-surrounding`][struct@crate::IMContext#retrieve-surrounding] signal on the input method;
349    /// in response to this signal, a widget should provide as much context as
350    /// is available, up to an entire paragraph, by calling
351    /// [`set_surrounding()`][Self::set_surrounding()].
352    ///
353    /// Note that there is no obligation for a widget to respond to the
354    /// `::retrieve-surrounding` signal, so input methods must be prepared to
355    /// function without context.
356    ///
357    /// # Deprecated since 4.2
358    ///
359    /// Use [`surrounding_with_selection()`][Self::surrounding_with_selection()] instead.
360    ///
361    /// # Returns
362    ///
363    /// `TRUE` if surrounding text was provided; in this case
364    ///    you must free the result stored in `text`.
365    ///
366    /// ## `text`
367    /// location to store a UTF-8 encoded
368    ///   string of text holding context around the insertion point.
369    ///   If the function returns [`true`], then you must free the result
370    ///   stored in this location with g_free().
371    ///
372    /// ## `cursor_index`
373    /// location to store byte index of the insertion
374    ///   cursor within @text.
375    #[cfg_attr(feature = "v4_2", deprecated = "Since 4.2")]
376    #[allow(deprecated)]
377    #[doc(alias = "gtk_im_context_get_surrounding")]
378    #[doc(alias = "get_surrounding")]
379    fn surrounding(&self) -> Option<(glib::GString, i32)> {
380        unsafe {
381            let mut text = std::ptr::null_mut();
382            let mut cursor_index = std::mem::MaybeUninit::uninit();
383            let ret = from_glib(ffi::gtk_im_context_get_surrounding(
384                self.as_ref().to_glib_none().0,
385                &mut text,
386                cursor_index.as_mut_ptr(),
387            ));
388            if ret {
389                Some((from_glib_full(text), cursor_index.assume_init()))
390            } else {
391                None
392            }
393        }
394    }
395
396    /// Retrieves context around the insertion point.
397    ///
398    /// Input methods typically want context in order to constrain input
399    /// text based on existing text; this is important for languages such
400    /// as Thai where only some sequences of characters are allowed.
401    ///
402    /// This function is implemented by emitting the
403    /// [`retrieve-surrounding`][struct@crate::IMContext#retrieve-surrounding] signal on the input method;
404    /// in response to this signal, a widget should provide as much context as
405    /// is available, up to an entire paragraph, by calling
406    /// [`set_surrounding_with_selection()`][Self::set_surrounding_with_selection()].
407    ///
408    /// Note that there is no obligation for a widget to respond to the
409    /// `::retrieve-surrounding` signal, so input methods must be prepared to
410    /// function without context.
411    ///
412    /// # Returns
413    ///
414    /// `TRUE` if surrounding text was provided; in this case
415    ///   you must free the result stored in `text`.
416    ///
417    /// ## `text`
418    /// location to store a UTF-8 encoded
419    ///   string of text holding context around the insertion point.
420    ///   If the function returns [`true`], then you must free the result
421    ///   stored in this location with g_free().
422    ///
423    /// ## `cursor_index`
424    /// location to store byte index of the insertion
425    ///   cursor within @text.
426    ///
427    /// ## `anchor_index`
428    /// location to store byte index of the selection
429    ///   bound within @text
430    #[cfg(feature = "v4_2")]
431    #[cfg_attr(docsrs, doc(cfg(feature = "v4_2")))]
432    #[doc(alias = "gtk_im_context_get_surrounding_with_selection")]
433    #[doc(alias = "get_surrounding_with_selection")]
434    fn surrounding_with_selection(&self) -> Option<(glib::GString, i32, i32)> {
435        unsafe {
436            let mut text = std::ptr::null_mut();
437            let mut cursor_index = std::mem::MaybeUninit::uninit();
438            let mut anchor_index = std::mem::MaybeUninit::uninit();
439            let ret = from_glib(ffi::gtk_im_context_get_surrounding_with_selection(
440                self.as_ref().to_glib_none().0,
441                &mut text,
442                cursor_index.as_mut_ptr(),
443                anchor_index.as_mut_ptr(),
444            ));
445            if ret {
446                Some((
447                    from_glib_full(text),
448                    cursor_index.assume_init(),
449                    anchor_index.assume_init(),
450                ))
451            } else {
452                None
453            }
454        }
455    }
456
457    /// Notify the input method that a change such as a change in cursor
458    /// position has been made.
459    ///
460    /// This will typically cause the input method to clear the preedit state.
461    #[doc(alias = "gtk_im_context_reset")]
462    fn reset(&self) {
463        unsafe {
464            ffi::gtk_im_context_reset(self.as_ref().to_glib_none().0);
465        }
466    }
467
468    /// Set the client widget for the input context.
469    ///
470    /// This is the [`Widget`][crate::Widget] holding the input focus. This widget is
471    /// used in order to correctly position status windows, and may
472    /// also be used for purposes internal to the input method.
473    /// ## `widget`
474    /// the client widget. This may be [`None`] to indicate
475    ///   that the previous client widget no longer exists.
476    #[doc(alias = "gtk_im_context_set_client_widget")]
477    fn set_client_widget(&self, widget: Option<&impl IsA<Widget>>) {
478        unsafe {
479            ffi::gtk_im_context_set_client_widget(
480                self.as_ref().to_glib_none().0,
481                widget.map(|p| p.as_ref()).to_glib_none().0,
482            );
483        }
484    }
485
486    /// Notify the input method that a change in cursor
487    /// position has been made.
488    ///
489    /// The location is relative to the client widget.
490    /// ## `area`
491    /// new location
492    #[doc(alias = "gtk_im_context_set_cursor_location")]
493    fn set_cursor_location(&self, area: &gdk::Rectangle) {
494        unsafe {
495            ffi::gtk_im_context_set_cursor_location(
496                self.as_ref().to_glib_none().0,
497                area.to_glib_none().0,
498            );
499        }
500    }
501
502    /// Sets surrounding context around the insertion point and preedit
503    /// string.
504    ///
505    /// This function is expected to be called in response to the
506    /// [`retrieve-surrounding`][struct@crate::IMContext#retrieve-surrounding] signal, and will
507    /// likely have no effect if called at other times.
508    ///
509    /// # Deprecated since 4.2
510    ///
511    /// Use [`set_surrounding_with_selection()`][Self::set_surrounding_with_selection()] instead
512    /// ## `text`
513    /// text surrounding the insertion point, as UTF-8.
514    ///   the preedit string should not be included within @text
515    /// ## `len`
516    /// the length of @text, or -1 if @text is nul-terminated
517    /// ## `cursor_index`
518    /// the byte index of the insertion cursor within @text.
519    #[cfg_attr(feature = "v4_2", deprecated = "Since 4.2")]
520    #[allow(deprecated)]
521    #[doc(alias = "gtk_im_context_set_surrounding")]
522    fn set_surrounding(&self, text: &str, cursor_index: i32) {
523        let len = text.len() as _;
524        unsafe {
525            ffi::gtk_im_context_set_surrounding(
526                self.as_ref().to_glib_none().0,
527                text.to_glib_none().0,
528                len,
529                cursor_index,
530            );
531        }
532    }
533
534    /// Sets surrounding context around the insertion point and preedit
535    /// string. This function is expected to be called in response to the
536    /// [`retrieve_surrounding`][struct@crate::IMContext#retrieve_surrounding] signal, and will likely
537    /// have no effect if called at other times.
538    /// ## `text`
539    /// text surrounding the insertion point, as UTF-8.
540    ///   the preedit string should not be included within @text
541    /// ## `len`
542    /// the length of @text, or -1 if @text is nul-terminated
543    /// ## `cursor_index`
544    /// the byte index of the insertion cursor within @text
545    /// ## `anchor_index`
546    /// the byte index of the selection bound within @text
547    #[cfg(feature = "v4_2")]
548    #[cfg_attr(docsrs, doc(cfg(feature = "v4_2")))]
549    #[doc(alias = "gtk_im_context_set_surrounding_with_selection")]
550    fn set_surrounding_with_selection(&self, text: &str, cursor_index: i32, anchor_index: i32) {
551        let len = text.len() as _;
552        unsafe {
553            ffi::gtk_im_context_set_surrounding_with_selection(
554                self.as_ref().to_glib_none().0,
555                text.to_glib_none().0,
556                len,
557                cursor_index,
558                anchor_index,
559            );
560        }
561    }
562
563    /// Sets whether the IM context should use the preedit string
564    /// to display feedback.
565    ///
566    /// If @use_preedit is [`false`] (default is [`true`]), then the IM context
567    /// may use some other method to display feedback, such as displaying
568    /// it in a child of the root window.
569    /// ## `use_preedit`
570    /// whether the IM context should use the preedit string.
571    #[doc(alias = "gtk_im_context_set_use_preedit")]
572    fn set_use_preedit(&self, use_preedit: bool) {
573        unsafe {
574            ffi::gtk_im_context_set_use_preedit(
575                self.as_ref().to_glib_none().0,
576                use_preedit.into_glib(),
577            );
578        }
579    }
580
581    /// Additional hints that allow input methods to fine-tune
582    /// their behaviour.
583    #[doc(alias = "input-hints")]
584    fn input_hints(&self) -> InputHints {
585        ObjectExt::property(self.as_ref(), "input-hints")
586    }
587
588    /// Additional hints that allow input methods to fine-tune
589    /// their behaviour.
590    #[doc(alias = "input-hints")]
591    fn set_input_hints(&self, input_hints: InputHints) {
592        ObjectExt::set_property(self.as_ref(), "input-hints", input_hints)
593    }
594
595    /// The purpose of the text field that the `GtkIMContext is connected to.
596    ///
597    /// This property can be used by on-screen keyboards and other input
598    /// methods to adjust their behaviour.
599    #[doc(alias = "input-purpose")]
600    fn input_purpose(&self) -> InputPurpose {
601        ObjectExt::property(self.as_ref(), "input-purpose")
602    }
603
604    /// The purpose of the text field that the `GtkIMContext is connected to.
605    ///
606    /// This property can be used by on-screen keyboards and other input
607    /// methods to adjust their behaviour.
608    #[doc(alias = "input-purpose")]
609    fn set_input_purpose(&self, input_purpose: InputPurpose) {
610        ObjectExt::set_property(self.as_ref(), "input-purpose", input_purpose)
611    }
612
613    /// The ::commit signal is emitted when a complete input sequence
614    /// has been entered by the user.
615    ///
616    /// If the commit comes after a preediting sequence, the
617    /// ::commit signal is emitted after ::preedit-end.
618    ///
619    /// This can be a single character immediately after a key press or
620    /// the final result of preediting.
621    /// ## `str`
622    /// the completed character(s) entered by the user
623    #[doc(alias = "commit")]
624    fn connect_commit<F: Fn(&Self, &str) + 'static>(&self, f: F) -> SignalHandlerId {
625        unsafe extern "C" fn commit_trampoline<P: IsA<IMContext>, F: Fn(&P, &str) + 'static>(
626            this: *mut ffi::GtkIMContext,
627            str: *mut std::ffi::c_char,
628            f: glib::ffi::gpointer,
629        ) {
630            let f: &F = &*(f as *const F);
631            f(
632                IMContext::from_glib_borrow(this).unsafe_cast_ref(),
633                &glib::GString::from_glib_borrow(str),
634            )
635        }
636        unsafe {
637            let f: Box_<F> = Box_::new(f);
638            connect_raw(
639                self.as_ptr() as *mut _,
640                c"commit".as_ptr() as *const _,
641                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
642                    commit_trampoline::<Self, F> as *const (),
643                )),
644                Box_::into_raw(f),
645            )
646        }
647    }
648
649    /// The ::delete-surrounding signal is emitted when the input method
650    /// needs to delete all or part of the context surrounding the cursor.
651    /// ## `offset`
652    /// the character offset from the cursor position of the text
653    ///   to be deleted. A negative value indicates a position before
654    ///   the cursor.
655    /// ## `n_chars`
656    /// the number of characters to be deleted
657    ///
658    /// # Returns
659    ///
660    /// [`true`] if the signal was handled.
661    #[doc(alias = "delete-surrounding")]
662    fn connect_delete_surrounding<F: Fn(&Self, i32, i32) -> bool + 'static>(
663        &self,
664        f: F,
665    ) -> SignalHandlerId {
666        unsafe extern "C" fn delete_surrounding_trampoline<
667            P: IsA<IMContext>,
668            F: Fn(&P, i32, i32) -> bool + 'static,
669        >(
670            this: *mut ffi::GtkIMContext,
671            offset: std::ffi::c_int,
672            n_chars: std::ffi::c_int,
673            f: glib::ffi::gpointer,
674        ) -> glib::ffi::gboolean {
675            let f: &F = &*(f as *const F);
676            f(
677                IMContext::from_glib_borrow(this).unsafe_cast_ref(),
678                offset,
679                n_chars,
680            )
681            .into_glib()
682        }
683        unsafe {
684            let f: Box_<F> = Box_::new(f);
685            connect_raw(
686                self.as_ptr() as *mut _,
687                c"delete-surrounding".as_ptr() as *const _,
688                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
689                    delete_surrounding_trampoline::<Self, F> as *const (),
690                )),
691                Box_::into_raw(f),
692            )
693        }
694    }
695
696    /// Emitted when the filtered keys do not compose to a single valid character.
697    /// ## `str`
698    /// the completed character(s) entered by the user
699    ///
700    /// # Returns
701    ///
702    /// true if the IM context avoid beeping on invalid composition
703    #[cfg(feature = "v4_22")]
704    #[cfg_attr(docsrs, doc(cfg(feature = "v4_22")))]
705    #[doc(alias = "invalid-composition")]
706    fn connect_invalid_composition<F: Fn(&Self, &str) -> bool + 'static>(
707        &self,
708        f: F,
709    ) -> SignalHandlerId {
710        unsafe extern "C" fn invalid_composition_trampoline<
711            P: IsA<IMContext>,
712            F: Fn(&P, &str) -> bool + 'static,
713        >(
714            this: *mut ffi::GtkIMContext,
715            str: *mut std::ffi::c_char,
716            f: glib::ffi::gpointer,
717        ) -> glib::ffi::gboolean {
718            let f: &F = &*(f as *const F);
719            f(
720                IMContext::from_glib_borrow(this).unsafe_cast_ref(),
721                &glib::GString::from_glib_borrow(str),
722            )
723            .into_glib()
724        }
725        unsafe {
726            let f: Box_<F> = Box_::new(f);
727            connect_raw(
728                self.as_ptr() as *mut _,
729                c"invalid-composition".as_ptr() as *const _,
730                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
731                    invalid_composition_trampoline::<Self, F> as *const (),
732                )),
733                Box_::into_raw(f),
734            )
735        }
736    }
737
738    /// The ::preedit-changed signal is emitted whenever the preedit sequence
739    /// currently being entered has changed.
740    ///
741    /// It is also emitted at the end of a preedit sequence, in which case
742    /// [`preedit_string()`][Self::preedit_string()] returns the empty string.
743    #[doc(alias = "preedit-changed")]
744    fn connect_preedit_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
745        unsafe extern "C" fn preedit_changed_trampoline<P: IsA<IMContext>, F: Fn(&P) + 'static>(
746            this: *mut ffi::GtkIMContext,
747            f: glib::ffi::gpointer,
748        ) {
749            let f: &F = &*(f as *const F);
750            f(IMContext::from_glib_borrow(this).unsafe_cast_ref())
751        }
752        unsafe {
753            let f: Box_<F> = Box_::new(f);
754            connect_raw(
755                self.as_ptr() as *mut _,
756                c"preedit-changed".as_ptr() as *const _,
757                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
758                    preedit_changed_trampoline::<Self, F> as *const (),
759                )),
760                Box_::into_raw(f),
761            )
762        }
763    }
764
765    /// The ::preedit-end signal is emitted when a preediting sequence
766    /// has been completed or canceled.
767    #[doc(alias = "preedit-end")]
768    fn connect_preedit_end<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
769        unsafe extern "C" fn preedit_end_trampoline<P: IsA<IMContext>, F: Fn(&P) + 'static>(
770            this: *mut ffi::GtkIMContext,
771            f: glib::ffi::gpointer,
772        ) {
773            let f: &F = &*(f as *const F);
774            f(IMContext::from_glib_borrow(this).unsafe_cast_ref())
775        }
776        unsafe {
777            let f: Box_<F> = Box_::new(f);
778            connect_raw(
779                self.as_ptr() as *mut _,
780                c"preedit-end".as_ptr() as *const _,
781                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
782                    preedit_end_trampoline::<Self, F> as *const (),
783                )),
784                Box_::into_raw(f),
785            )
786        }
787    }
788
789    /// The ::preedit-start signal is emitted when a new preediting sequence
790    /// starts.
791    #[doc(alias = "preedit-start")]
792    fn connect_preedit_start<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
793        unsafe extern "C" fn preedit_start_trampoline<P: IsA<IMContext>, F: Fn(&P) + 'static>(
794            this: *mut ffi::GtkIMContext,
795            f: glib::ffi::gpointer,
796        ) {
797            let f: &F = &*(f as *const F);
798            f(IMContext::from_glib_borrow(this).unsafe_cast_ref())
799        }
800        unsafe {
801            let f: Box_<F> = Box_::new(f);
802            connect_raw(
803                self.as_ptr() as *mut _,
804                c"preedit-start".as_ptr() as *const _,
805                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
806                    preedit_start_trampoline::<Self, F> as *const (),
807                )),
808                Box_::into_raw(f),
809            )
810        }
811    }
812
813    /// The ::retrieve-surrounding signal is emitted when the input method
814    /// requires the context surrounding the cursor.
815    ///
816    /// The callback should set the input method surrounding context by
817    /// calling the [`set_surrounding()`][Self::set_surrounding()] method.
818    ///
819    /// # Returns
820    ///
821    /// [`true`] if the signal was handled.
822    #[doc(alias = "retrieve-surrounding")]
823    fn connect_retrieve_surrounding<F: Fn(&Self) -> bool + 'static>(
824        &self,
825        f: F,
826    ) -> SignalHandlerId {
827        unsafe extern "C" fn retrieve_surrounding_trampoline<
828            P: IsA<IMContext>,
829            F: Fn(&P) -> bool + 'static,
830        >(
831            this: *mut ffi::GtkIMContext,
832            f: glib::ffi::gpointer,
833        ) -> glib::ffi::gboolean {
834            let f: &F = &*(f as *const F);
835            f(IMContext::from_glib_borrow(this).unsafe_cast_ref()).into_glib()
836        }
837        unsafe {
838            let f: Box_<F> = Box_::new(f);
839            connect_raw(
840                self.as_ptr() as *mut _,
841                c"retrieve-surrounding".as_ptr() as *const _,
842                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
843                    retrieve_surrounding_trampoline::<Self, F> as *const (),
844                )),
845                Box_::into_raw(f),
846            )
847        }
848    }
849
850    #[doc(alias = "input-hints")]
851    fn connect_input_hints_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
852        unsafe extern "C" fn notify_input_hints_trampoline<
853            P: IsA<IMContext>,
854            F: Fn(&P) + 'static,
855        >(
856            this: *mut ffi::GtkIMContext,
857            _param_spec: glib::ffi::gpointer,
858            f: glib::ffi::gpointer,
859        ) {
860            let f: &F = &*(f as *const F);
861            f(IMContext::from_glib_borrow(this).unsafe_cast_ref())
862        }
863        unsafe {
864            let f: Box_<F> = Box_::new(f);
865            connect_raw(
866                self.as_ptr() as *mut _,
867                c"notify::input-hints".as_ptr() as *const _,
868                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
869                    notify_input_hints_trampoline::<Self, F> as *const (),
870                )),
871                Box_::into_raw(f),
872            )
873        }
874    }
875
876    #[doc(alias = "input-purpose")]
877    fn connect_input_purpose_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
878        unsafe extern "C" fn notify_input_purpose_trampoline<
879            P: IsA<IMContext>,
880            F: Fn(&P) + 'static,
881        >(
882            this: *mut ffi::GtkIMContext,
883            _param_spec: glib::ffi::gpointer,
884            f: glib::ffi::gpointer,
885        ) {
886            let f: &F = &*(f as *const F);
887            f(IMContext::from_glib_borrow(this).unsafe_cast_ref())
888        }
889        unsafe {
890            let f: Box_<F> = Box_::new(f);
891            connect_raw(
892                self.as_ptr() as *mut _,
893                c"notify::input-purpose".as_ptr() as *const _,
894                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
895                    notify_input_purpose_trampoline::<Self, F> as *const (),
896                )),
897                Box_::into_raw(f),
898            )
899        }
900    }
901}
902
903impl<O: IsA<IMContext>> IMContextExt for O {}