<NME> winit.rs
<BEF> use std::{
    cell::RefCell,
    rc::Rc,
    sync::{
        atomic::{AtomicBool, Ordering},
        Arc, Mutex,
    },
};

use smithay::{
use smithay::backend::renderer::ImportMem;
#[cfg(feature = "egl")]
use smithay::{
    backend::{
        allocator::dmabuf::Dmabuf,
        renderer::{ImportDma, ImportEgl},
    },
    delegate_dmabuf,
    wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportError},
};
use smithay::{
    backend::{
        renderer::{
            damage::{DamageTrackedRenderer, DamageTrackedRendererError},
            element::AsRenderElements,
            gles2::{Gles2Renderer, Gles2Texture},
        },
        winit::{self, WinitEvent, WinitGraphicsBackend},
        SwapBuffersError,
use crate::AnvilState;

pub fn run_winit(
    display: &mut Display,
    event_loop: &mut EventLoop<AnvilState>,
    log: Logger,
) -> Result<(), ()> {
    let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?;

    #[cfg(feature = "egl")]
    let egl_buffer_reader = Rc::new(RefCell::new(
        if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display) {
            info!(log, "EGL hardware-acceleration enabled");
            Some(egl_buffer_reader)
        } else {

pub struct WinitData {
    backend: WinitGraphicsBackend,
    damage_tracked_renderer: DamageTrackedRenderer,
    #[cfg(feature = "egl")]
    dmabuf_state: Option<(DmabufState, DmabufGlobal)>,
    full_redraw: u8,
    #[cfg(feature = "debug")]
    pub fps: fps_ticker::Fps,
}

#[cfg(feature = "egl")]
    #[cfg(not(feature = "egl"))]
    let buffer_utils = BufferUtils::new(log.clone());

    let name = display.add_socket_auto().unwrap().into_string().unwrap();
    info!(log, "Listening on wayland socket"; "name" => name.clone());
    ::std::env::set_var("WAYLAND_DISPLAY", name);

    let running = Arc::new(AtomicBool::new(true));

    /*
     * Initialize the globals
     */

    init_shm_global(display, vec![], log.clone());

    let (compositor_token, _, _, window_map) = init_shell(display, buffer_utils, log.clone());

    let dnd_icon = Arc::new(Mutex::new(None));

    let dnd_icon2 = dnd_icon.clone();
    init_data_device(
        display,
        move |event| match event {
            DataDeviceEvent::DnDStarted { icon, .. } => {
                *dnd_icon2.lock().unwrap() = icon;
    #[cfg_attr(not(feature = "egl"), allow(unused_mut))]
    let (mut backend, mut winit) = match winit::init(log.clone()) {
        Ok(ret) => ret,
        Err(err) => {
            slog::crit!(log, "Failed to initialize Winit backend: {}", err);
            return;
        }
    };
        log.clone(),
    );

    let (mut seat, _) = Seat::new(display, "winit".into(), compositor_token, log.clone());

    let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default));

            model: "Winit".into(),
        },
        log.clone(),
    );
    let _global = output.create_global::<AnvilState<WinitData>>(&display.handle());
    output.change_current_state(Some(mode), Some(Transform::Flipped180), None, Some((0, 0).into()));
    output.set_preferred(mode);

    #[cfg(feature = "debug")]
    let fps_image =
        .expect("Failed to initialize the keyboard");

    let (output, _) = Output::new(
        display,
        "Winit".into(),
        PhysicalProperties {
            width: 0,
            &fps_image.to_rgba8(),
            (fps_image.width() as i32, fps_image.height() as i32).into(),
            false,
        )
        .expect("Unable to upload FPS texture");
    #[cfg(feature = "debug")]
    let mut fps_element = FpsElement::new(fps_texture);

    let data = {
        #[cfg(feature = "egl")]
        let dmabuf_state = if backend.renderer().bind_wl_display(&display.handle()).is_ok() {
            info!(log, "EGL hardware-acceleration enabled");
            let dmabuf_formats = backend.renderer().dmabuf_formats().cloned().collect::<Vec<_>>();
            let mut state = DmabufState::new();
            let global = state.create_global::<AnvilState<WinitData>, _>(
                &display.handle(),
                dmabuf_formats,
                log.clone(),
            );
            Some((state, global))
        } else {
            None
        };

        let damage_tracked_renderer = DamageTrackedRenderer::from_output(&output);

        WinitData {
            backend,
        keyboard,
        window_map.clone(),
        (0, 0),
        running.clone(),
        pointer_location.clone(),
    ));

    info!(log, "Initialization completed, starting the main loop.");

    while running.load(Ordering::SeqCst) {
        input.dispatch_new_events().unwrap();

        // drawing logic

    info!(log, "Initialization completed, starting the main loop.");

    let mut pointer_element = PointerElement::<Gles2Texture>::default();

    while state.running.load(Ordering::SeqCst) {
        if winit
            .dispatch_new_events(|event| match event {
                WinitEvent::Resized { size, .. } => {
                    // We only have one output
                    let output = state.space.outputs().next().unwrap().clone();
                    state.space.map_output(&output, (0, 0));
                    let mode = Mode {
                        size,
                        refresh: 60_000,
                    };
                    output.change_current_state(Some(mode), None, None, None);
                    output.set_preferred(mode);
                    crate::shell::fixup_positions(&mut state.space);
                }
                WinitEvent::Input(event) => {
                    state.process_input_event_windowed(&display.handle(), event, OUTPUT_NAME)
                }
                _ => (),
            })
            .is_err()
        {
            state.running.store(false, Ordering::SeqCst);
            break;
        }

        // drawing logic
        {
            let backend = &mut state.backend_data.backend;

            let mut cursor_guard = state.cursor_status.lock().unwrap();

            }
        }

        let mut state = AnvilState::default();

        if event_loop
            .dispatch(Some(::std::time::Duration::from_millis(16)), &mut state)
            .is_err()
        {
            running.store(false, Ordering::SeqCst);
        } else {
            if state.need_wayland_dispatch {
                display
                    .dispatch(std::time::Duration::from_millis(0), &mut state)
                    .unwrap();
            }
            display.flush_clients(&mut state);
            window_map.borrow_mut().refresh();
        }
    }
            #[cfg(feature = "debug")]
            let fps = state.backend_data.fps.avg().round() as u32;
            #[cfg(feature = "debug")]
            fps_element.update_fps(fps);

            let full_redraw = &mut state.backend_data.full_redraw;
            *full_redraw = full_redraw.saturating_sub(1);
            let space = &mut state.space;
            let damage_tracked_renderer = &mut state.backend_data.damage_tracked_renderer;

            let input_method = state.seat.input_method().unwrap();
            let dnd_icon = state.dnd_icon.as_ref();

            let scale = Scale::from(output.current_scale().fractional_scale());
            let cursor_hotspot = if let CursorImageStatus::Surface(ref surface) = *cursor_guard {
                compositor::with_states(surface, |states| {
                    states
                        .data_map
                        .get::<Mutex<CursorImageAttributes>>()
                        .unwrap()
                        .lock()
                        .unwrap()
                        .hotspot
                })
            } else {
                (0, 0).into()
            };
            let cursor_pos = state.pointer_location - cursor_hotspot.to_f64();
            let cursor_pos_scaled = cursor_pos.to_physical(scale).to_i32_round();

            let render_res = backend.bind().and_then(|_| {
                let age = if *full_redraw > 0 {
                    0
                } else {
                    backend.buffer_age().unwrap_or(0)
                };

                let renderer = backend.renderer();

                let mut elements = Vec::<CustomRenderElements<Gles2Renderer>>::new();

                elements.extend(pointer_element.render_elements(cursor_pos_scaled, scale));

                // draw input method surface if any
                let rectangle = input_method.coordinates();
                let position = Point::from((
                    rectangle.loc.x + rectangle.size.w,
                    rectangle.loc.y + rectangle.size.h,
                ));
                input_method.with_surface(|surface| {
                    elements.extend(AsRenderElements::<Gles2Renderer>::render_elements(
                        &smithay::desktop::space::SurfaceTree::from_surface(surface),
                        position.to_physical_precise_round(scale),
                        scale,
                    ));
                });

                // draw the dnd icon if any
                if let Some(surface) = dnd_icon {
                    if surface.alive() {
                        elements.extend(AsRenderElements::<Gles2Renderer>::render_elements(
                            &smithay::desktop::space::SurfaceTree::from_surface(surface),
                            cursor_pos_scaled,
                            scale,
                        ));
                    }
                }

                #[cfg(feature = "debug")]
                elements.push(CustomRenderElements::Fps(fps_element.clone()));

                render_output(
                    &output,
                    space,
                    &elements,
                    renderer,
                    damage_tracked_renderer,
                    age,
                    &log,
                )
                .map_err(|err| match err {
                    DamageTrackedRendererError::Rendering(err) => err.into(),
                    _ => unreachable!(),
                })
            });

            match render_res {
                Ok((damage, states)) => {
                    if let Some(damage) = damage {
                        if let Err(err) = backend.submit(Some(&*damage)) {
                            warn!(log, "Failed to submit buffer: {}", err);
                        }
                    }
                    backend.window().set_cursor_visible(cursor_visible);

                    // Send frame events so that client start drawing their next frame
                    state.send_frames(&output, &states);
                }
                Err(SwapBuffersError::ContextLost(err)) => {
                    error!(log, "Critical Rendering Error: {}", err);
                    state.running.store(false, Ordering::SeqCst);
                }
                Err(err) => warn!(log, "Rendering error: {}", err),
            }
        }

        let mut calloop_data = CalloopData { state, display };
        let result = event_loop.dispatch(Some(Duration::from_millis(16)), &mut calloop_data);
        CalloopData { state, display } = calloop_data;

        if result.is_err() {
            state.running.store(false, Ordering::SeqCst);
        } else {
            state.space.refresh();
            state.popups.cleanup();
            display.flush_clients().unwrap();
        }

        #[cfg(feature = "debug")]
        state.backend_data.fps.tick();
    }
}

<MSG> anvil: restore correct dispatching of wayland clients

<DFF> @@ -1,10 +1,7 @@
 use std::{
     cell::RefCell,
     rc::Rc,
-    sync::{
-        atomic::{AtomicBool, Ordering},
-        Arc, Mutex,
-    },
+    sync::{atomic::Ordering, Arc, Mutex},
 };
 
 use smithay::{
@@ -30,15 +27,15 @@ use crate::shell::init_shell;
 use crate::AnvilState;
 
 pub fn run_winit(
-    display: &mut Display,
-    event_loop: &mut EventLoop<AnvilState>,
+    display: Rc<RefCell<Display>>,
+    mut event_loop: EventLoop<AnvilState>,
     log: Logger,
 ) -> Result<(), ()> {
     let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?;
 
     #[cfg(feature = "egl")]
     let egl_buffer_reader = Rc::new(RefCell::new(
-        if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display) {
+        if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display.borrow()) {
             info!(log, "EGL hardware-acceleration enabled");
             Some(egl_buffer_reader)
         } else {
@@ -57,25 +54,31 @@ pub fn run_winit(
     #[cfg(not(feature = "egl"))]
     let buffer_utils = BufferUtils::new(log.clone());
 
-    let name = display.add_socket_auto().unwrap().into_string().unwrap();
+    let name = display
+        .borrow_mut()
+        .add_socket_auto()
+        .unwrap()
+        .into_string()
+        .unwrap();
     info!(log, "Listening on wayland socket"; "name" => name.clone());
     ::std::env::set_var("WAYLAND_DISPLAY", name);
 
-    let running = Arc::new(AtomicBool::new(true));
+    let mut state = AnvilState::default();
 
     /*
      * Initialize the globals
      */
 
-    init_shm_global(display, vec![], log.clone());
+    init_shm_global(&mut display.borrow_mut(), vec![], log.clone());
 
-    let (compositor_token, _, _, window_map) = init_shell(display, buffer_utils, log.clone());
+    let (compositor_token, _, _, window_map) =
+        init_shell(&mut display.borrow_mut(), buffer_utils, log.clone());
 
     let dnd_icon = Arc::new(Mutex::new(None));
 
     let dnd_icon2 = dnd_icon.clone();
     init_data_device(
-        display,
+        &mut display.borrow_mut(),
         move |event| match event {
             DataDeviceEvent::DnDStarted { icon, .. } => {
                 *dnd_icon2.lock().unwrap() = icon;
@@ -90,7 +93,12 @@ pub fn run_winit(
         log.clone(),
     );
 
-    let (mut seat, _) = Seat::new(display, "winit".into(), compositor_token, log.clone());
+    let (mut seat, _) = Seat::new(
+        &mut display.borrow_mut(),
+        "winit".into(),
+        compositor_token,
+        log.clone(),
+    );
 
     let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default));
 
@@ -107,7 +115,7 @@ pub fn run_winit(
         .expect("Failed to initialize the keyboard");
 
     let (output, _) = Output::new(
-        display,
+        &mut display.borrow_mut(),
         "Winit".into(),
         PhysicalProperties {
             width: 0,
@@ -142,13 +150,13 @@ pub fn run_winit(
         keyboard,
         window_map.clone(),
         (0, 0),
-        running.clone(),
+        state.running.clone(),
         pointer_location.clone(),
     ));
 
     info!(log, "Initialization completed, starting the main loop.");
 
-    while running.load(Ordering::SeqCst) {
+    while state.running.load(Ordering::SeqCst) {
         input.dispatch_new_events().unwrap();
 
         // drawing logic
@@ -192,20 +200,13 @@ pub fn run_winit(
             }
         }
 
-        let mut state = AnvilState::default();
-
         if event_loop
             .dispatch(Some(::std::time::Duration::from_millis(16)), &mut state)
             .is_err()
         {
-            running.store(false, Ordering::SeqCst);
+            state.running.store(false, Ordering::SeqCst);
         } else {
-            if state.need_wayland_dispatch {
-                display
-                    .dispatch(std::time::Duration::from_millis(0), &mut state)
-                    .unwrap();
-            }
-            display.flush_clients(&mut state);
+            display.borrow_mut().flush_clients(&mut state);
             window_map.borrow_mut().refresh();
         }
     }

anvil: restore correct dispatching of wayland clients