gtk4/
event_controller_key.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{boxed::Box as Box_, mem::transmute};
4
5use gdk::Key;
6use glib::{signal::connect_raw, translate::*, SignalHandlerId};
7
8use crate::{ffi, prelude::*, EventControllerKey};
9
10impl EventControllerKey {
11    /// Emitted whenever a key is pressed.
12    /// ## `keyval`
13    /// the pressed key.
14    /// ## `keycode`
15    /// the raw code of the pressed key.
16    /// ## `state`
17    /// the bitmask, representing the state of modifier keys and pointer buttons.
18    ///
19    /// # Returns
20    ///
21    /// [`true`] if the key press was handled, [`false`] otherwise.
22    pub fn connect_key_pressed<
23        F: Fn(&EventControllerKey, Key, u32, gdk::ModifierType) -> glib::Propagation + 'static,
24    >(
25        &self,
26        f: F,
27    ) -> SignalHandlerId {
28        unsafe extern "C" fn key_pressed_trampoline<
29            F: Fn(&EventControllerKey, Key, u32, gdk::ModifierType) -> glib::Propagation + 'static,
30        >(
31            this: *mut ffi::GtkEventControllerKey,
32            keyval: libc::c_uint,
33            keycode: libc::c_uint,
34            state: gdk::ffi::GdkModifierType,
35            f: glib::ffi::gpointer,
36        ) -> glib::ffi::gboolean {
37            let f: &F = &*(f as *const F);
38            f(
39                &from_glib_borrow(this),
40                from_glib(keyval),
41                keycode,
42                from_glib(state),
43            )
44            .into_glib()
45        }
46        unsafe {
47            let f: Box_<F> = Box_::new(f);
48            connect_raw(
49                self.as_ptr() as *mut _,
50                b"key-pressed\0".as_ptr() as *const _,
51                Some(transmute::<*const (), unsafe extern "C" fn()>(
52                    key_pressed_trampoline::<F> as *const (),
53                )),
54                Box_::into_raw(f),
55            )
56        }
57    }
58
59    /// Emitted whenever a key is released.
60    /// ## `keyval`
61    /// the released key.
62    /// ## `keycode`
63    /// the raw code of the released key.
64    /// ## `state`
65    /// the bitmask, representing the state of modifier keys and pointer buttons.
66    pub fn connect_key_released<
67        F: Fn(&EventControllerKey, Key, u32, gdk::ModifierType) + 'static,
68    >(
69        &self,
70        f: F,
71    ) -> SignalHandlerId {
72        unsafe extern "C" fn key_released_trampoline<
73            F: Fn(&EventControllerKey, Key, u32, gdk::ModifierType) + 'static,
74        >(
75            this: *mut ffi::GtkEventControllerKey,
76            keyval: libc::c_uint,
77            keycode: libc::c_uint,
78            state: gdk::ffi::GdkModifierType,
79            f: glib::ffi::gpointer,
80        ) {
81            let f: &F = &*(f as *const F);
82            f(
83                &from_glib_borrow(this),
84                from_glib(keyval),
85                keycode,
86                from_glib(state),
87            )
88        }
89        unsafe {
90            let f: Box_<F> = Box_::new(f);
91            connect_raw(
92                self.as_ptr() as *mut _,
93                b"key-released\0".as_ptr() as *const _,
94                Some(transmute::<*const (), unsafe extern "C" fn()>(
95                    key_released_trampoline::<F> as *const (),
96                )),
97                Box_::into_raw(f),
98            )
99        }
100    }
101}