/// Updates the window that has this seat's keyboard/pointer focus.
///
/// This function must be called whenever an event occurs that could potentially imply a
/// change of the focus. Some non-multi-seat-aware window managers treat all focus changes
/// as changes of the core-seat focus. In these cases the X server will not send FocusIn/Out
/// events for additional seats. By calling this function on every keyboard/pointer input,
/// we update the focus as necessary.
Updates the window that has this seat's keyboard/pointer focus.
This function must be called whenever an event occurs that could potentially imply a
change of the focus. Some non-multi-seat-aware window managers treat all focus changes
as changes of the core-seat focus. In these cases the X server will not send FocusIn/Out
events for additional seats. By calling this function on every keyboard/pointer input,
we update the focus as necessary.
Updates the window that has this seat ' s keyboard / pointer focus . This function must be called whenever an event occurs that could potentially imply a change of the focus . Some non - multi - seat - aware window managers treat all focus changes as changes of the core - seat focus . In these cases the X server will not send FocusIn / Out events for additional seats . By calling this function on every keyboard / pointer input we update the focus as necessary .
fn update_seat_focus<F>(
        seat: &mut Seat,
        component: SeatFocus,
        wt: &EventLoopWindowTarget<T>,
        mut focus: Option<ffi::xcb_window_t>,
        callback: &mut F,
    ) where
        F: FnMut(Event<'_, T>),
    {
        let old_focus_count = seat.kb_focus.is_some() as u8 + seat.ptr_focus.is_some() as u8;
        let seat_focus = match component {
            KbFocus => &mut seat.kb_focus,
            PtrFocus => &mut seat.ptr_focus,
        };
        if *seat_focus == focus {
            return;
        }
        if let Some(new) = focus {
            if !Self::window_exists(wt, new) {
                if seat_focus.is_none() {
                    return;
                }
                focus = None;
            }
        }
        if seat_focus.is_some() != focus.is_some() {
            let new_focus_count = if focus.is_some() {
                old_focus_count + 1
            } else {
                old_focus_count - 1
            };
            if (new_focus_count == 0) != (old_focus_count == 0) {
                let state_details = if new_focus_count == 0 {
                    0
                } else {
                    ffi::XCB_XKB_STATE_PART_MODIFIER_STATE as _
                };
                let details = ffi::xcb_xkb_select_events_details_t {
                    affect_state: ffi::XCB_XKB_STATE_PART_MODIFIER_STATE as _,
                    state_details,
                    ..Default::default()
                };
                let pending = wt.xconn.select_xkb_event_details(
                    seat.keyboard,
                    ffi::XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
                    &details,
                );
                if let Err(e) = wt.xconn.check_pending1(pending) {
                    const MAX_ERRORS: usize = 5;
                    if seat.num_errors < MAX_ERRORS {
                        seat.num_errors += 1;
                        log::warn!("Could not change XKB selected events: {}", e);
                        if seat.num_errors == MAX_ERRORS {
                            log::warn!("Future warnings of this kind will be suppressed");
                        }
                    }
                }
            }
        }
        let device_id = mkdid(seat.keyboard);
        if let Some(focus) = *seat_focus {
            let event = match component {
                KbFocus => WindowEvent::Focused(false),
                PtrFocus => WindowEvent::CursorLeft { device_id },
            };
            callback(Event::WindowEvent {
                window_id: mkwid(focus),
                event,
            });
        }
        *seat_focus = focus;
        if let Some(focus) = *seat_focus {
            let event = match component {
                KbFocus => WindowEvent::Focused(true),
                PtrFocus => WindowEvent::CursorEntered { device_id },
            };
            callback(Event::WindowEvent {
                window_id: mkwid(focus),
                event,
            });
            callback(Event::WindowEvent {
                window_id: mkwid(focus),
                event: WindowEvent::ModifiersChanged(seat.current_modifiers),
            });
        }
    }
fn update_seat_focus < F > ( seat : & mut Seat , component : SeatFocus , wt : & EventLoopWindowTarget < T > , mut focus : Option < ffi :: xcb_window_t > , callback : & mut F , ) where F : FnMut ( Event < ' _ , T > ) , { let old_focus_count = seat . kb_focus . is_some ( ) as u8 + seat . ptr_focus . is_some ( ) as u8 ; let seat_focus = match component { KbFocus => & mut seat . kb_focus , PtrFocus => & mut seat . ptr_focus , } ; if * seat_focus == focus { return ; } if let Some ( new ) = focus { if ! Self :: window_exists ( wt , new ) { if seat_focus . is_none ( ) { return ; } focus = None ; } } if seat_focus . is_some ( ) != focus . is_some ( ) { let new_focus_count = if focus . is_some ( ) { old_focus_count + 1 } else { old_focus_count - 1 } ; if ( new_focus_count == 0 ) != ( old_focus_count == 0 ) { let state_details = if new_focus_count == 0 { 0 } else { ffi :: XCB_XKB_STATE_PART_MODIFIER_STATE as _ } ; let details = ffi :: xcb_xkb_select_events_details_t { affect_state : ffi :: XCB_XKB_STATE_PART_MODIFIER_STATE as _ , state_details , .. Default :: default ( ) } ; let pending = wt . xconn . select_xkb_event_details ( seat . keyboard , ffi :: XCB_XKB_EVENT_TYPE_STATE_NOTIFY , & details , ) ; if let Err ( e ) = wt . xconn . check_pending1 ( pending ) { const MAX_ERRORS : usize = 5 ; if seat . num_errors < MAX_ERRORS { seat . num_errors += 1 ; log :: warn ! ( " " e ) ; if seat . num_errors == MAX_ERRORS { log :: warn ! ( " " ) ; } } } } } let device_id = mkdid ( seat . keyboard ) ; if let Some ( focus ) = * seat_focus { let event = match component { KbFocus => WindowEvent :: Focused ( false ) , PtrFocus => WindowEvent :: CursorLeft { device_id } , } ; callback ( Event :: WindowEvent { window_id : mkwid ( focus ) , event , } ) ; } * seat_focus = focus ; if let Some ( focus ) = * seat_focus { let event = match component { KbFocus => WindowEvent :: Focused ( true ) , PtrFocus => WindowEvent :: CursorEntered { device_id } , } ; callback ( Event :: WindowEvent { window_id : mkwid ( focus ) , event , } ) ; callback ( Event :: WindowEvent { window_id : mkwid ( focus ) , event : WindowEvent :: ModifiersChanged ( seat . current_modifiers ) , } ) ; } }
Updates the window that has this seat's keyboard/pointer focus.
Updates the window that has this seat ' s keyboard / pointer focus .
seat
&mut Seat
component
SeatFocus
wt
&EventLoopWindowTarget<T>
focus
Option<ffi::xcb_window_t>
callback
&mut F