Function set_event_handler_local

Source
pub fn set_event_handler_local<P, H>(proxy: &P, handler: H)
where P: OwnedProxy, P::Api: CreateEventHandler<H>, <P::Api as CreateEventHandler<H>>::EventHandler: 'static,
Expand description

Sets the !Send event handler of the proxy.

This function is the same as set_event_handler except that the event handler does not have to implement Send and the queue of the proxy must be a local queue.

§Panic

This function panics whenever set_event_handler panics and also if the queue of the proxy is not a local queue.

§Example

let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_local_queue(c"");
let display: WlDisplay = queue.display();
let sync = display.sync();
let done = Rc::new(Cell::new(false));

// Attach the event handler.
let done2 = done.clone();
proxy::set_event_handler_local(&sync, WlCallback::on_done(move |_, _| {
    done2.set(true);
}));

// Wait for the compositor to send the `done` message.
queue.dispatch_roundtrip_blocking().unwrap();

// The event handler sets the value to `true`.
assert!(done.get());
Examples found in repository?
examples/keyboard-events/main.rs (lines 34-40)
26fn main() {
27    let lib = Libwayland::open().unwrap();
28    let con = lib.connect_to_default_display().unwrap();
29    let queue = con.create_local_queue(c"keyboard-events");
30    let singletons = get_singletons(&queue.display());
31    let simple_window = simple_window::prepare(singletons);
32
33    let wl_registry = queue.display::<WlDisplay>().get_registry();
34    proxy::set_event_handler_local(
35        &wl_registry,
36        RegistryEventHandler {
37            wl_registry: wl_registry.clone(),
38            seats: Default::default(),
39        },
40    );
41
42    while !simple_window.exit.get() {
43        queue.dispatch_blocking().unwrap();
44    }
45}
46
47struct RegistryEventHandler {
48    wl_registry: WlRegistry,
49    seats: RefCell<HashMap<u32, Rc<Seat>>>,
50}
51
52struct Seat {
53    wl_seat: WlSeat,
54    wl_keyboard: RefCell<Option<WlKeyboard>>,
55}
56
57#[derive(Clone)]
58struct SeatEventHandler(Rc<Seat>);
59
60impl WlRegistryEventHandler for RegistryEventHandler {
61    fn global(&self, _slf: &WlRegistryRef, name: u32, interface: &str, version: u32) {
62        if interface == WlSeat::INTERFACE {
63            let wl_seat = self.wl_registry.bind::<WlSeat>(name, version.min(5));
64            let seat = Rc::new(Seat {
65                wl_seat: wl_seat.clone(),
66                wl_keyboard: Default::default(),
67            });
68            self.seats.borrow_mut().insert(name, seat.clone());
69            proxy::set_event_handler_local(&wl_seat, SeatEventHandler(seat));
70        }
71    }
72
73    fn global_remove(&self, _slf: &WlRegistryRef, name: u32) {
74        if let Some(seat) = self.seats.borrow_mut().remove(&name) {
75            if let Some(kb) = seat.wl_keyboard.take() {
76                if proxy::version(&*kb) >= WlKeyboard::REQ__RELEASE__SINCE {
77                    kb.release();
78                } else {
79                    proxy::destroy(&kb);
80                }
81            }
82            if proxy::version(&*seat.wl_seat) >= WlSeat::REQ__RELEASE__SINCE {
83                seat.wl_seat.release();
84            } else {
85                proxy::destroy(&seat.wl_seat);
86            }
87        }
88    }
89}
90
91impl WlSeatEventHandler for SeatEventHandler {
92    fn capabilities(&self, _slf: &WlSeatRef, capabilities: WlSeatCapability) {
93        let kb = &mut *self.0.wl_keyboard.borrow_mut();
94        if capabilities.contains(WlSeatCapability::KEYBOARD) {
95            if kb.is_none() {
96                let wl_keyboard = self.0.wl_seat.get_keyboard();
97                proxy::set_event_handler_local(&wl_keyboard, self.clone());
98                *kb = Some(wl_keyboard);
99            }
100        } else {
101            if let Some(kb) = kb.take() {
102                if proxy::version(&*kb) >= WlKeyboard::REQ__RELEASE__SINCE {
103                    kb.release();
104                } else {
105                    proxy::destroy(&kb);
106                }
107            }
108        }
109    }
More examples
Hide additional examples
examples/poll-integration/../common/simple_window.rs (line 65)
53pub fn prepare(singletons: Singletons) -> SimpleWindow {
54    let lib = Libwayland::open().unwrap();
55    let con = lib.connect_to_default_display().unwrap();
56    let queue = con.create_local_queue(c"simple-window");
57    let display: WlDisplay = queue.display();
58
59    // We have a hard dependency on these globals.
60    let wl_compositor = singletons.get::<WlCompositor>(1, 1);
61    let wl_shm = singletons.get::<WlShm>(1, 1);
62    let xdg_wm_base = singletons.get::<XdgWmBase>(1, 1);
63    let wp_viewporter = singletons.get::<WpViewporter>(1, 1);
64
65    proxy::set_event_handler_local(&xdg_wm_base, XdgWmPingPong);
66
67    // Create the window.
68    let buffer = {
69        let mut tempfile = tempfile().unwrap();
70        tempfile.write_all(&[0, 0, 0, 255]).unwrap();
71        let pool = wl_shm.create_pool(tempfile.as_fd(), 4);
72        let buffer = pool.create_buffer(0, 1, 1, 4, WlShmFormat::ARGB8888);
73        pool.destroy();
74        buffer
75    };
76    let wl_surface = wl_compositor.create_surface();
77    let wp_viewport = wp_viewporter.get_viewport(&wl_surface);
78    let xdg_surface = xdg_wm_base.get_xdg_surface(&wl_surface);
79    let xdg_toplevel = xdg_surface.get_toplevel();
80    xdg_toplevel.set_title("simple-window");
81    wl_surface.commit();
82
83    let exit = Rc::new(Cell::new(false));
84
85    let event_handler = WindowEventHandler {
86        state: Rc::new(WindowState {
87            surface: wl_surface.clone(),
88            buffer,
89            viewport: wp_viewport.clone(),
90            exit: exit.clone(),
91            attached_buffer: Cell::new(false),
92            pending_size: Cell::new((DEFAULT_WIDTH, DEFAULT_HEIGHT)),
93            current_size: Cell::new((0, 0)),
94        }),
95    };
96    proxy::set_event_handler_local(&xdg_surface, event_handler.clone());
97    proxy::set_event_handler_local(&xdg_toplevel, event_handler.clone());
98
99    // If we have the cursor shape manager, create a new registry to handle seats
100    // and give the pointers the default shape when they enter our window.
101    if let Some(cursor_shape) = singletons.get_opt::<WpCursorShapeManagerV1>(1, 1) {
102        let registry = display.get_registry();
103        proxy::set_event_handler_local(
104            &registry,
105            SeatRegistryHandler {
106                registry: registry.clone(),
107                wp_cursor_shape_manager_v1: cursor_shape,
108                seats: Default::default(),
109            },
110        );
111    }
112
113    SimpleWindow {
114        exit,
115        wl_compositor,
116        wl_shm,
117        xdg_wm_base,
118        wp_viewporter,
119        wl_surface,
120        wp_viewport,
121        xdg_surface,
122        xdg_toplevel,
123    }
124}
125
126struct SeatRegistryHandler {
127    registry: WlRegistry,
128    wp_cursor_shape_manager_v1: WpCursorShapeManagerV1,
129    seats: RefCell<HashMap<u32, Rc<RefCell<SeatData>>>>,
130}
131
132impl WlRegistryEventHandler for SeatRegistryHandler {
133    fn global(&self, _slf: &WlRegistryRef, name: u32, interface: &str, version: u32) {
134        if interface != WlSeat::INTERFACE {
135            return;
136        }
137        let seat: WlSeat = self.registry.bind(name, version.min(5));
138        let data = Rc::new(RefCell::new(SeatData {
139            seat: seat.clone(),
140            pointer: None,
141            shape: None,
142        }));
143        proxy::set_event_handler_local(
144            &seat,
145            SeatEventHandler {
146                wp_cursor_shape_manager_v1: self.wp_cursor_shape_manager_v1.clone(),
147                data: data.clone(),
148            },
149        );
150        self.seats.borrow_mut().insert(name, data);
151    }
152
153    fn global_remove(&self, _slf: &WlRegistryRef, name: u32) {
154        let seats = &mut *self.seats.borrow_mut();
155        let Some(seat) = seats.remove(&name) else {
156            return;
157        };
158        let data = &mut *seat.borrow_mut();
159        data.destroy_pointer();
160        if proxy::version(&*data.seat) >= WlSeat::REQ__RELEASE__SINCE {
161            data.seat.release();
162        } else {
163            proxy::destroy(&data.seat);
164        }
165    }
166}
167
168struct SeatEventHandler {
169    wp_cursor_shape_manager_v1: WpCursorShapeManagerV1,
170    data: Rc<RefCell<SeatData>>,
171}
172
173struct SeatData {
174    seat: WlSeat,
175    pointer: Option<WlPointer>,
176    shape: Option<WpCursorShapeDeviceV1>,
177}
178
179impl SeatData {
180    fn destroy_pointer(&mut self) {
181        if let Some(shape) = self.shape.take() {
182            shape.destroy();
183        }
184        if let Some(pointer) = self.pointer.take() {
185            if proxy::version(&*pointer) >= WlPointer::REQ__RELEASE__SINCE {
186                pointer.release();
187            } else {
188                proxy::destroy(&pointer);
189            }
190        }
191    }
192}
193
194impl WlSeatEventHandler for SeatEventHandler {
195    fn capabilities(&self, _slf: &WlSeatRef, capabilities: WlSeatCapability) {
196        let data = &mut *self.data.borrow_mut();
197        if capabilities.contains(WlSeatCapability::POINTER) {
198            if data.pointer.is_some() {
199                return;
200            }
201            let pointer = data.seat.get_pointer();
202            let shape = self.wp_cursor_shape_manager_v1.get_pointer(&pointer);
203            proxy::set_event_handler_local(
204                &pointer,
205                PointerEventHandler {
206                    shape: shape.clone(),
207                },
208            );
209            data.pointer = Some(pointer);
210            data.shape = Some(shape);
211        } else {
212            data.destroy_pointer();
213        }
214    }