@@ -118,8 +118,8 @@ pub(crate) struct WaylandClientState {
loop_handle: LoopHandle<'static, WaylandClientStatePtr>,
cursor_icon_name: String,
cursor: Cursor,
- clipboard: Clipboard,
- primary: Primary,
+ clipboard: Option<Clipboard>,
+ primary: Option<Primary>,
event_loop: Option<EventLoop<'static, WaylandClientStatePtr>>,
common: LinuxCommon,
}
@@ -163,6 +163,12 @@ impl WaylandClientStatePtr {
state.mouse_focused_window = Some(window);
}
}
+ if state.windows.is_empty() {
+ // Drop the clipboard to prevent a seg fault after we've closed all Wayland connections.
+ state.clipboard = None;
+ state.primary = None;
+ state.common.signal.stop();
+ }
}
}
@@ -278,8 +284,8 @@ impl WaylandClient {
cursor_icon_name: "arrow".to_string(),
enter_token: None,
cursor,
- clipboard,
- primary,
+ clipboard: Some(clipboard),
+ primary: Some(primary),
event_loop: Some(event_loop),
}));
@@ -378,17 +384,29 @@ impl LinuxClient for WaylandClient {
}
fn write_to_primary(&self, item: crate::ClipboardItem) {
- self.0.borrow_mut().primary.set_contents(item.text);
+ self.0
+ .borrow_mut()
+ .primary
+ .as_mut()
+ .unwrap()
+ .set_contents(item.text);
}
fn write_to_clipboard(&self, item: crate::ClipboardItem) {
- self.0.borrow_mut().clipboard.set_contents(item.text);
+ self.0
+ .borrow_mut()
+ .clipboard
+ .as_mut()
+ .unwrap()
+ .set_contents(item.text);
}
fn read_from_primary(&self) -> Option<crate::ClipboardItem> {
self.0
.borrow_mut()
.primary
+ .as_mut()
+ .unwrap()
.get_contents()
.ok()
.map(|s| crate::ClipboardItem {
@@ -401,6 +419,8 @@ impl LinuxClient for WaylandClient {
self.0
.borrow_mut()
.clipboard
+ .as_mut()
+ .unwrap()
.get_contents()
.ok()
.map(|s| crate::ClipboardItem {
@@ -68,6 +68,7 @@ unsafe impl HasRawDisplayHandle for RawWindow {
pub struct WaylandWindowState {
xdg_surface: xdg_surface::XdgSurface,
pub surface: wl_surface::WlSurface,
+ decoration: Option<zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1>,
toplevel: xdg_toplevel::XdgToplevel,
viewport: Option<wp_viewport::WpViewport>,
outputs: HashSet<ObjectId>,
@@ -90,11 +91,13 @@ pub struct WaylandWindowStatePtr {
}
impl WaylandWindowState {
+ #[allow(clippy::too_many_arguments)]
pub(crate) fn new(
surface: wl_surface::WlSurface,
xdg_surface: xdg_surface::XdgSurface,
- viewport: Option<wp_viewport::WpViewport>,
toplevel: xdg_toplevel::XdgToplevel,
+ decoration: Option<zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1>,
+ viewport: Option<wp_viewport::WpViewport>,
client: WaylandClientStatePtr,
globals: Globals,
options: WindowParams,
@@ -132,6 +135,7 @@ impl WaylandWindowState {
Self {
xdg_surface,
surface,
+ decoration,
toplevel,
viewport,
globals,
@@ -158,16 +162,27 @@ impl Drop for WaylandWindow {
let mut state = self.0.state.borrow_mut();
let surface_id = state.surface.id();
let client = state.client.clone();
+
state.renderer.destroy();
+ if let Some(decoration) = &state.decoration {
+ decoration.destroy();
+ }
state.toplevel.destroy();
+ if let Some(viewport) = &state.viewport {
+ viewport.destroy();
+ }
state.xdg_surface.destroy();
state.surface.destroy();
let state_ptr = self.0.clone();
- state.globals.executor.spawn(async move {
- state_ptr.close();
- client.drop_window(&surface_id)
- });
+ state
+ .globals
+ .executor
+ .spawn(async move {
+ state_ptr.close();
+ client.drop_window(&surface_id)
+ })
+ .detach();
drop(state);
}
}
@@ -197,13 +212,18 @@ impl WaylandWindow {
}
// Attempt to set up window decorations based on the requested configuration
- if let Some(decoration_manager) = globals.decoration_manager.as_ref() {
- let decoration =
- decoration_manager.get_toplevel_decoration(&toplevel, &globals.qh, surface.id());
-
- // Request client side decorations if possible
- decoration.set_mode(zxdg_toplevel_decoration_v1::Mode::ClientSide);
- }
+ let decoration = globals
+ .decoration_manager
+ .as_ref()
+ .map(|decoration_manager| {
+ let decoration = decoration_manager.get_toplevel_decoration(
+ &toplevel,
+ &globals.qh,
+ surface.id(),
+ );
+ decoration.set_mode(zxdg_toplevel_decoration_v1::Mode::ClientSide);
+ decoration
+ });
let viewport = globals
.viewporter
@@ -216,8 +236,9 @@ impl WaylandWindow {
state: Rc::new(RefCell::new(WaylandWindowState::new(
surface.clone(),
xdg_surface,
- viewport,
toplevel,
+ decoration,
+ viewport,
client,
globals,
params,
@@ -319,7 +340,7 @@ impl WaylandWindowStatePtr {
}
result
} else {
- false
+ true
}
}
_ => false,