1- use std:: collections:: HashMap ;
1+ use std:: collections:: { HashMap , HashSet } ;
22
33use tokio:: sync:: mpsc:: { self , UnboundedReceiver , UnboundedSender } ;
44
@@ -52,6 +52,10 @@ pub enum Event {
5252 id : ObjectId ,
5353 name : Option < String > ,
5454 } ,
55+ OutputRemoved {
56+ id : ObjectId ,
57+ name : Option < String > ,
58+ } ,
5559
5660 SeatFocusedOutput {
5761 id : ObjectId ,
@@ -70,8 +74,8 @@ pub enum Event {
7074}
7175
7276struct State {
73- outputs : Vec < WlOutput > ,
74- seats : Vec < WlSeat > ,
77+ outputs : HashMap < u32 , WlOutput > ,
78+ seats : HashMap < u32 , WlSeat > ,
7579 manager : Option < ZriverStatusManagerV1 > ,
7680 output_statuses : Vec < ZriverOutputStatusV1 > ,
7781 seat_statuses : Vec < ZriverSeatStatusV1 > ,
@@ -83,8 +87,8 @@ struct State {
8387impl State {
8488 fn new ( tx : UnboundedSender < Event > ) -> Self {
8589 Self {
86- outputs : Vec :: new ( ) ,
87- seats : Vec :: new ( ) ,
90+ outputs : HashMap :: new ( ) ,
91+ seats : HashMap :: new ( ) ,
8892 manager : None ,
8993 output_statuses : Vec :: new ( ) ,
9094 seat_statuses : Vec :: new ( ) ,
@@ -115,13 +119,13 @@ impl State {
115119
116120 fn create_status_for_all ( & mut self , qh : & QueueHandle < Self > ) {
117121 if self . manager . is_some ( ) {
118- let outs = self . outputs . clone ( ) ;
119- for o in & outs {
120- self . maybe_create_status_for_output ( qh, o ) ;
122+ let outputs : Vec < _ > = self . outputs . values ( ) . cloned ( ) . collect ( ) ;
123+ for output in & outputs {
124+ self . maybe_create_status_for_output ( qh, output ) ;
121125 }
122- let seats = self . seats . clone ( ) ;
123- for s in & seats {
124- self . maybe_create_status_for_seat ( qh, s ) ;
126+ let seats: Vec < _ > = self . seats . values ( ) . cloned ( ) . collect ( ) ;
127+ for seat in & seats {
128+ self . maybe_create_status_for_seat ( qh, seat ) ;
125129 }
126130 }
127131 }
@@ -188,15 +192,13 @@ impl Dispatch<WlRegistry, ()> for State {
188192 } => match interface. as_str ( ) {
189193 "wl_output" => {
190194 let output = registry. bind :: < WlOutput , _ , _ > ( name, version. min ( 4 ) , qh, ( ) ) ;
191- state. outputs . push ( output) ;
192- let last = state. outputs . last ( ) . unwrap ( ) . clone ( ) ;
193- state. maybe_create_status_for_output ( qh, & last) ;
195+ state. maybe_create_status_for_output ( qh, & output) ;
196+ state. outputs . insert ( name, output) ;
194197 }
195198 "wl_seat" => {
196199 let seat = registry. bind :: < WlSeat , _ , _ > ( name, version. min ( 5 ) , qh, ( ) ) ;
197- state. seats . push ( seat) ;
198- let last = state. seats . last ( ) . unwrap ( ) . clone ( ) ;
199- state. maybe_create_status_for_seat ( qh, & last) ;
200+ state. maybe_create_status_for_seat ( qh, & seat) ;
201+ state. seats . insert ( name, seat) ;
200202 }
201203 "zriver_status_manager_v1" => {
202204 let mgr =
@@ -206,6 +208,11 @@ impl Dispatch<WlRegistry, ()> for State {
206208 }
207209 _ => { }
208210 } ,
211+ wl_registry:: Event :: GlobalRemove { name } => {
212+ if !state. remove_output ( name) {
213+ state. seats . remove ( & name) ;
214+ }
215+ }
209216 _ => { }
210217 }
211218 }
@@ -344,6 +351,31 @@ fn parse_u32_array(bytes: &[u8]) -> Vec<u32> {
344351 v
345352}
346353
354+ impl State {
355+ fn remove_output ( & mut self , global : u32 ) -> bool {
356+ let Some ( output) = self . outputs . remove ( & global) else {
357+ return false ;
358+ } ;
359+ let id = output. id ( ) ;
360+ let label = self . output_label ( & id) ;
361+ let protocol_id = id. protocol_id ( ) ;
362+
363+ let mut removed_status_ids = HashSet :: new ( ) ;
364+ for ( status_id, owner) in & self . output_status_owner {
365+ if owner. protocol_id ( ) == protocol_id {
366+ removed_status_ids. insert ( * status_id) ;
367+ }
368+ }
369+ self . output_status_owner
370+ . retain ( |status_id, _| !removed_status_ids. contains ( status_id) ) ;
371+ self . output_statuses
372+ . retain ( |status| !removed_status_ids. contains ( & status. id ( ) . protocol_id ( ) ) ) ;
373+ self . output_info . remove ( & protocol_id) ;
374+ let _ = self . tx . send ( Event :: OutputRemoved { id, name : label } ) ;
375+ true
376+ }
377+ }
378+
347379pub struct RiverStatus ;
348380
349381impl RiverStatus {
0 commit comments