@@ -35,12 +35,12 @@ use std::{
3535} ;
3636#[ cfg( tablet) ]
3737const TABLET_MANAGER_MAX_VERSION : u32 = 2 ;
38- use wayland_client:: { Connection , globals:: registry_queue_init} ;
38+ use wayland_client:: { Connection , backend :: WaylandError , globals:: registry_queue_init} ;
3939#[ cfg( tablet) ]
4040use wayland_protocols:: wp:: tablet:: zv2:: client:: zwp_tablet_manager_v2:: ZwpTabletManagerV2 ;
4141use wayland_protocols_wlr:: screencopy:: v1:: client:: zwlr_screencopy_manager_v1:: ZwlrScreencopyManagerV1 ;
4242
43- use super :: state:: WaylandState ;
43+ use super :: state:: { OverlaySuppression , WaylandState } ;
4444use crate :: {
4545 RESUME_SESSION_ENV ,
4646 capture:: { CaptureManager , CaptureOutcome } ,
@@ -641,12 +641,8 @@ impl WaylandBackend {
641641 }
642642
643643 // Apply any completed portal fallback captures without blocking.
644- state
645- . frozen
646- . poll_portal_capture ( & mut state. surface , & mut state. input_state ) ;
647- state
648- . zoom
649- . poll_portal_capture ( & mut state. surface , & mut state. input_state ) ;
644+ state. frozen . poll_portal_capture ( & mut state. input_state ) ;
645+ state. zoom . poll_portal_capture ( & mut state. input_state ) ;
650646
651647 if tray_action_flag
652648 . as_ref ( )
@@ -656,9 +652,46 @@ impl WaylandBackend {
656652 process_tray_action ( & mut state) ;
657653 }
658654
659- // Dispatch all pending events (blocking) but check should_exit after each batch
660- match event_queue. blocking_dispatch ( & mut state) {
661- Ok ( _) => {
655+ let capture_active = state. capture . is_in_progress ( )
656+ || state. frozen . is_in_progress ( )
657+ || state. zoom . is_in_progress ( )
658+ || state. overlay_suppressed ( ) ;
659+
660+ let mut dispatch_error: Option < anyhow:: Error > = None ;
661+ if capture_active {
662+ if let Err ( e) = event_queue. dispatch_pending ( & mut state) {
663+ dispatch_error = Some ( anyhow:: anyhow!( "Wayland event queue error: {}" , e) ) ;
664+ }
665+
666+ if dispatch_error. is_none ( )
667+ && let Err ( e) = event_queue. flush ( )
668+ {
669+ dispatch_error = Some ( anyhow:: anyhow!( "Wayland flush error: {}" , e) ) ;
670+ }
671+
672+ if dispatch_error. is_none ( )
673+ && let Some ( guard) = event_queue. prepare_read ( )
674+ {
675+ match guard. read ( ) {
676+ Ok ( _) => {
677+ if let Err ( e) = event_queue. dispatch_pending ( & mut state) {
678+ dispatch_error =
679+ Some ( anyhow:: anyhow!( "Wayland event queue error: {}" , e) ) ;
680+ }
681+ }
682+ Err ( WaylandError :: Io ( err) )
683+ if err. kind ( ) == std:: io:: ErrorKind :: WouldBlock => { }
684+ Err ( err) => {
685+ dispatch_error = Some ( anyhow:: anyhow!( "Wayland read error: {}" , err) ) ;
686+ }
687+ }
688+ }
689+ } else if let Err ( e) = event_queue. blocking_dispatch ( & mut state) {
690+ dispatch_error = Some ( anyhow:: anyhow!( "Wayland event queue error: {}" , e) ) ;
691+ }
692+
693+ match dispatch_error {
694+ None => {
662695 // Check immediately after dispatch returns
663696 if state. input_state . should_exit {
664697 info ! ( "Exit requested after dispatch, breaking event loop" ) ;
@@ -679,13 +712,20 @@ impl WaylandBackend {
679712 state. input_state . needs_redraw = true ;
680713 }
681714 }
682- Err ( e) => {
715+ Some ( e) => {
683716 warn ! ( "Event queue error: {}" , e) ;
684- loop_error = Some ( anyhow :: anyhow! ( "Wayland event queue error: {}" , e ) ) ;
717+ loop_error = Some ( e ) ;
685718 break ;
686719 }
687720 }
688721
722+ if capture_active {
723+ let _ = conn. flush ( ) ;
724+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 10 ) ) ;
725+ }
726+
727+ state. apply_capture_completion ( ) ;
728+
689729 if state. input_state . take_pending_frozen_toggle ( ) {
690730 if !state. frozen_enabled ( ) {
691731 warn ! (
@@ -702,24 +742,20 @@ impl WaylandBackend {
702742 } else {
703743 log:: info!( "Frozen mode: using screencopy fast path" ) ;
704744 }
705- if let Err ( err) = state. frozen . start_capture (
706- & state. shm ,
707- & mut state. surface ,
708- & qh,
709- use_fallback,
710- & mut state. input_state ,
711- & state. tokio_handle ,
712- ) {
745+ state. enter_overlay_suppression ( OverlaySuppression :: Frozen ) ;
746+ if let Err ( err) = state
747+ . frozen
748+ . start_capture ( use_fallback, & state. tokio_handle )
749+ {
713750 warn ! ( "Frozen capture failed to start: {}" , err) ;
714- state
715- . frozen
716- . cancel ( & mut state. surface , & mut state. input_state ) ;
751+ state. exit_overlay_suppression ( OverlaySuppression :: Frozen ) ;
752+ state. frozen . cancel ( & mut state. input_state ) ;
717753 }
718754 }
719755 }
720756
721757 if let Some ( action) = state. input_state . take_pending_zoom_action ( ) {
722- state. handle_zoom_action ( action, & qh ) ;
758+ state. handle_zoom_action ( action) ;
723759 }
724760
725761 // Check for completed capture operations
0 commit comments