diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index 06543a7..892322f 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -72,7 +72,7 @@ pub struct Wayland { impl Wayland { pub fn new() -> Result { let egl_raw_handles = get_sk_egl()?; - let mut renderer = unsafe { + let renderer = unsafe { GlesRenderer::new(EGLContext::from_raw( egl_raw_handles.display, egl_raw_handles.config, diff --git a/src/wayland/panel_item.rs b/src/wayland/panel_item.rs index c707493..104c5a9 100644 --- a/src/wayland/panel_item.rs +++ b/src/wayland/panel_item.rs @@ -470,7 +470,18 @@ impl PanelItem { xdg_toplevel.configure_bounds(bounds.x as i32, bounds.y as i32); } } - let size = info.size.unwrap_or(Vector2::from([0; 2])); + let zero_size = Vector2::from([0; 2]); + let size = info.size.unwrap_or(zero_size); + // if size == zero_size && (info.states.contains(1) || info.states.contains(2)) { + // xdg_toplevel.configure( + // size.x as i32, + // size.y as i32, + // info.states + // .into_iter() + // .flat_map(|state| state.to_ne_bytes()) + // .collect::>(), + // ); + // } xdg_toplevel.configure( size.x as i32, size.y as i32, diff --git a/src/wayland/seat.rs b/src/wayland/seat.rs index 983630b..42d63d1 100644 --- a/src/wayland/seat.rs +++ b/src/wayland/seat.rs @@ -446,7 +446,7 @@ impl Dispatch, WaylandState> for WaylandState { hotspot_y, } => { if let Some(surface) = surface.as_ref() { - CoreSurface::add_to(&state.display, dh.clone(), surface, |_| ()); + CoreSurface::add_to(&state.display, dh.clone(), surface, || (), |_| ()); compositor::with_states(surface, |data| { data.data_map.insert_if_missing_threadsafe(|| { Arc::new(Mutex::new(Cursor { diff --git a/src/wayland/surface.rs b/src/wayland/surface.rs index 45c3030..4f7388f 100644 --- a/src/wayland/surface.rs +++ b/src/wayland/surface.rs @@ -50,6 +50,7 @@ pub struct CoreSurface { sk_tex: OnceCell>, sk_mat: OnceCell>>, material_offset: Mutex>, + on_mapped: Box, on_commit: Box, pub pending_material_applications: Registry, } @@ -59,6 +60,7 @@ impl CoreSurface { display: &Arc>>, dh: DisplayHandle, surface: &WlSurface, + on_mapped: impl Fn() + Send + Sync + 'static, on_commit: impl Fn(u32) + Send + Sync + 'static, ) { compositor::with_states(surface, |data| { @@ -71,6 +73,7 @@ impl CoreSurface { sk_tex: OnceCell::new(), sk_mat: OnceCell::new(), material_offset: Mutex::new(Delta::new(0)), + on_mapped: Box::new(on_mapped) as Box, on_commit: Box::new(on_commit) as Box, pending_material_applications: Registry::new(), }) @@ -125,9 +128,8 @@ impl CoreSurface { } let mut mapped_data = self.mapped_data.lock(); + let just_mapped = mapped_data.is_none(); self.with_states(|data| { - // let just_mapped = mapped_data.is_none(); - // if just_mapped { let renderer_surface_state = data .data_map .get::() @@ -165,6 +167,10 @@ impl CoreSurface { }; *mapped_data = Some(new_mapped_data); }); + drop(mapped_data); + if just_mapped { + (self.on_mapped)(); + } self.apply_surface_materials(); } diff --git a/src/wayland/xdg_shell.rs b/src/wayland/xdg_shell.rs index 43d7ca0..7eee842 100644 --- a/src/wayland/xdg_shell.rs +++ b/src/wayland/xdg_shell.rs @@ -253,21 +253,29 @@ impl Dispatch, WaylandState> for WaylandState debug!(?toplevel, ?xdg_surface, "Create XDG toplevel"); if toplevel.version() >= EVT_WM_CAPABILITIES_SINCE { - toplevel.wm_capabilities(vec![]); + toplevel.wm_capabilities(vec![2, 3, 4]); } - toplevel.configure(0, 0, vec![]); + toplevel.configure( + 0, + 0, + if toplevel.version() >= 2 { + vec![5, 6, 7, 8] + } else { + vec![] + }, + ); xdg_surface.configure(SERIAL_COUNTER.inc()); let client_credentials = client.get_credentials(&state.display_handle).ok(); let seat_data = state.seats.get(&client.id()).unwrap().clone(); - let toplevel_weak = toplevel.downgrade(); CoreSurface::add_to( &state.display, state.display_handle.clone(), &xdg_surface_data.lock().wl_surface(), - move |c| match c { - 0 => { - let toplevel = toplevel_weak.upgrade().unwrap(); + { + let toplevel = toplevel.downgrade(); + move || { + let toplevel = toplevel.upgrade().unwrap(); let toplevel_data = ToplevelData::get(&toplevel); let xdg_surface = toplevel_data.lock().xdg_surface(); let xdg_surface_data = XdgSurfaceData::get(&xdg_surface); @@ -283,10 +291,27 @@ impl Dispatch, WaylandState> for WaylandState toplevel_data.lock().panel_item_node.replace(node); xdg_surface_data.lock().panel_item = Arc::downgrade(&panel_item); } - _ => { - let toplevel = toplevel_weak.upgrade().unwrap(); + }, + { + let toplevel = toplevel.downgrade(); + move |_| { + let toplevel = toplevel.upgrade().unwrap(); let toplevel_data = ToplevelData::get(&toplevel); - let panel_item = toplevel_data.lock().panel_item().unwrap(); + let Some(panel_item) = toplevel_data.lock().panel_item() else { + // if the wayland toplevel isn't mapped, hammer it again with a configure until it cooperates + toplevel.configure( + 0, + 0, + if toplevel.version() >= 2 { + vec![5, 6, 7, 8] + } else { + vec![] + }, + ); + let xdg_surface = toplevel_data.lock().xdg_surface(); + xdg_surface.configure(SERIAL_COUNTER.inc()); + return + }; panel_item.commit_toplevel(); } }, @@ -335,19 +360,19 @@ impl Dispatch, WaylandState> for WaylandState &state.display, state.display_handle.clone(), &xdg_surface_data.lock().wl_surface.upgrade().unwrap(), - move |commit_count| match commit_count { - 0 => xdg_surface - .upgrade() - .unwrap() - .configure(SERIAL_COUNTER.inc()), - c => { - let xdg_popup = xdg_popup.upgrade().unwrap(); - let popup_data = PopupData::get(&xdg_popup); - let popup_data = popup_data.lock(); - // panel_item.commit_popup(popup_data); - if c == 1 { - panel_item.new_popup(&xdg_popup, &*popup_data); - } + move || { + let xdg_popup = xdg_popup.upgrade().unwrap(); + let popup_data = PopupData::get(&xdg_popup); + let popup_data = popup_data.lock(); + // panel_item.commit_popup(popup_data); + panel_item.new_popup(&xdg_popup, &*popup_data); + }, + move |commit_count| { + if commit_count == 0 { + xdg_surface + .upgrade() + .unwrap() + .configure(SERIAL_COUNTER.inc()) } }, );