feat: add nested Phase 0 compositor

This commit is contained in:
Samuel Onoja committed 2026-09-24 05:38:18 +01:00
1 parent aab447ef25
commit 475d433ec4
8 files changed
+2710 -2

No files matched your search

+129
View File
@@ -0,0 +1,129 @@
use smithay::{
desktop::{
PopupKind, PopupManager, Space, Window, find_popup_root_surface, get_popup_toplevel_coords,
},
reexports::wayland_server::protocol::{wl_seat, wl_surface::WlSurface},
utils::Serial,
wayland::{
compositor::with_states,
shell::xdg::{
PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler, XdgShellState,
XdgToplevelSurfaceData,
},
},
};
use crate::Ferese;
impl XdgShellHandler for Ferese {
fn xdg_shell_state(&mut self) -> &mut XdgShellState {
&mut self.xdg_shell_state
}
fn new_toplevel(&mut self, surface: ToplevelSurface) {
self.space
.map_element(Window::new_wayland_window(surface), (0, 0), true);
}
fn new_popup(&mut self, surface: PopupSurface, _positioner: PositionerState) {
self.unconstrain_popup(&surface);
if let Err(error) = self.popups.track_popup(PopupKind::Xdg(surface)) {
tracing::warn!(?error, "failed to track xdg popup");
}
}
fn reposition_request(
&mut self,
surface: PopupSurface,
positioner: PositionerState,
token: u32,
) {
surface.with_pending_state(|state| {
state.geometry = positioner.get_geometry();
state.positioner = positioner;
});
self.unconstrain_popup(&surface);
surface.send_repositioned(token);
}
fn move_request(&mut self, _: ToplevelSurface, _: wl_seat::WlSeat, _: Serial) {}
fn resize_request(
&mut self,
_: ToplevelSurface,
_: wl_seat::WlSeat,
_: Serial,
_: smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel::ResizeEdge,
) {
}
fn grab(&mut self, _: PopupSurface, _: wl_seat::WlSeat, _: Serial) {}
}
pub fn handle_commit(popups: &mut PopupManager, space: &Space<Window>, surface: &WlSurface) {
if let Some(window) = space
.elements()
.find(|window| {
window
.toplevel()
.is_some_and(|toplevel| toplevel.wl_surface() == surface)
})
.cloned()
{
let configured = with_states(surface, |states| {
states
.data_map
.get::<XdgToplevelSurfaceData>()
.expect("xdg toplevel state exists")
.lock()
.expect("xdg toplevel state is not poisoned")
.initial_configure_sent
});
if !configured {
window
.toplevel()
.expect("mapped window has a toplevel")
.send_configure();
}
}
popups.commit(surface);
if let Some(PopupKind::Xdg(popup)) = popups.find_popup(surface)
&& !popup.is_initial_configure_sent()
{
popup
.send_configure()
.expect("initial popup configure is valid");
}
}
impl Ferese {
fn unconstrain_popup(&self, popup: &PopupSurface) {
let Ok(root) = find_popup_root_surface(&PopupKind::Xdg(popup.clone())) else {
return;
};
let Some(window) = self.space.elements().find(|window| {
window
.toplevel()
.is_some_and(|toplevel| toplevel.wl_surface() == &root)
}) else {
return;
};
let Some(output) = self.space.outputs().next() else {
return;
};
let Some(output_geometry) = self.space.output_geometry(output) else {
return;
};
let Some(window_geometry) = self.space.element_geometry(window) else {
return;
};
let mut target = output_geometry;
target.loc -= get_popup_toplevel_coords(&PopupKind::Xdg(popup.clone()));
target.loc -= window_geometry.loc;
popup.with_pending_state(|state| {
state.geometry = state.positioner.get_unconstrained_geometry(target);
});
}
}