atagen

monolith

public
Star0
Watch0

Commit 3c5663c16f2a

tarball

atagen <boss@atagen.co>2026-10-19 10:59 UTC

1 file changed+22-13
xwayland: clear an X11-owned selection when Xwayland exits

disconnected dropped the X11Wm, which never reports cleared_selection, so a selection an X11 client owned stayed on the seat and every paste waited on a source that was gone.
Modified file: crates/monolith/src/xwayland.rs+22 additions−13 deletions
@@ -517,19 +517,7 @@ impl XwmHandler for State {
517517 }
518518
519519 fn cleared_selection(&mut self, _xwm: XwmId, selection: SelectionTarget) {
520- let (dh, seat) = (&self.core.display, &self.input.seat);
521- match selection {
522- SelectionTarget::Clipboard => {
523- if current_data_device_selection_userdata(seat).is_some() {
524- clear_data_device_selection(dh, seat);
525- }
526- }
527- SelectionTarget::Primary => {
528- if current_primary_selection_userdata(seat).is_some() {
529- clear_primary_selection(dh, seat);
530- }
531- }
532- }
520+ self.clear_x11_selection(selection);
533521 }
534522
535523 fn disconnected(&mut self, _xwm: XwmId) {
@@ -547,6 +535,8 @@ impl XwmHandler for State {
547535 x.wm = None;
548536 x.unmanaged.clear();
549537 }
538+ self.clear_x11_selection(SelectionTarget::Clipboard);
539+ self.clear_x11_selection(SelectionTarget::Primary);
550540 rearm(self);
551541 }
552542 }
@@ -575,6 +565,25 @@ pub fn fixed_size(window: &X11Surface) -> Option<Size<i32, Logical>> {
575565 }
576566
577567 impl State {
568+ /// Clears `selection` when an X11 client owns it, since a client-owned
569+ /// selection carries no user data. Xwayland dying takes the owner with it
570+ /// without a cleared_selection call.
571+ fn clear_x11_selection(&mut self, selection: SelectionTarget) {
572+ let (dh, seat) = (&self.core.display, &self.input.seat);
573+ match selection {
574+ SelectionTarget::Clipboard => {
575+ if current_data_device_selection_userdata(seat).is_some() {
576+ clear_data_device_selection(dh, seat);
577+ }
578+ }
579+ SelectionTarget::Primary => {
580+ if current_primary_selection_userdata(seat).is_some() {
581+ clear_primary_selection(dh, seat);
582+ }
583+ }
584+ }
585+ }
586+
578587 pub fn x11_window_id(&self, window: &X11Surface) -> Option<monolith_layout::WindowId> {
579588 self.wm
580589 .iter()