From 6813c6448e8346d3a7f120739c31b19801ee1c23 Mon Sep 17 00:00:00 2001 From: Justin Scroggins Date: Tue, 10 Nov 2026 20:32:44 -0500 Subject: [PATCH 1/3] Show a live preview of my own screen share instead of a blurred thumbnail card Sharing a screen in a Tiny call used to leave my own stage with a text card over a dimmed, cover-fitted copy of the start-of-share thumbnail. The share now paints a small live JPEG of what it sends (the camera's self-view size and rate), the stage and tile draw it Contain with Stop sharing over it, and it clears when the share stops. Camera and share can be on together, so the preview is its own slot: Call.share_view and a `share` flag on MediaResponse::SelfView (absent reads as the camera, so older mediad frames still parse). Until the first picture lands the card stays, without the thumbnail smear and without claiming nothing is shown. Adds e2e/scenarios/share-self-view and a tiny_sharing shot state. Co-Authored-By: Claude Sonnet 5.5 --- .../__pycache__/pr-gate.cpython-313.pyc | Bin 0 -> 15001 bytes crates/chatd/src/media.rs | 43 ++++- crates/mediad/src/discord_video.rs | 7 +- crates/mediad/src/picture/desktop.rs | 105 +++++++++--- crates/mediad/src/picture/phone.rs | 10 ++ crates/mediad/src/tiny.rs | 6 +- crates/mediad/src/video.rs | 157 ++++++++++++++++-- crates/protocol/src/call.rs | 27 ++- crates/tinyclient/src/gui/call.rs | 3 + crates/tinyclient/src/gui/call/dock.rs | 1 + .../tinyclient/src/gui/call/phone/screens.rs | 1 + crates/tinyclient/src/gui/call/security.rs | 1 + crates/tinyclient/src/gui/call/shot.rs | 17 +- crates/tinyclient/src/gui/mod.rs | 3 +- crates/tinyclient/src/gui/shot_demo.rs | 1 + crates/tinyclient/src/gui/shot_demo_live.rs | 1 + crates/tinyclient/src/gui/tiny/channel.rs | 62 +++++-- crates/tinyclient/src/gui/tiny/feed.rs | 22 ++- crates/tinyclient/src/gui/tiny/mod.rs | 10 ++ e2e/lab/__pycache__/common.cpython-313.pyc | Bin 0 -> 15747 bytes .../__pycache__/coordinated.cpython-313.pyc | Bin 0 -> 20963 bytes e2e/lab/__pycache__/lab.cpython-313.pyc | Bin 0 -> 36456 bytes .../test_coordinated.cpython-313.pyc | Bin 0 -> 31656 bytes e2e/lab/__pycache__/test_lab.cpython-313.pyc | Bin 0 -> 14200 bytes e2e/lab/__pycache__/test_mac.cpython-313.pyc | Bin 0 -> 4559 bytes .../test_orchestration.cpython-313.pyc | Bin 0 -> 55580 bytes .../__pycache__/_mac.cpython-313.pyc | Bin 0 -> 10430 bytes e2e/scenarios/share-self-view/README.md | 20 +++ e2e/scenarios/share-self-view/drive.linux.sh | 3 + e2e/scenarios/share-self-view/drive.macos.sh | 3 + e2e/scenarios/share-self-view/drive.py | 20 +++ .../share-self-view/drive.windows.ps1 | 3 + e2e/scenarios/share-self-view/scenario.json | 12 ++ 33 files changed, 461 insertions(+), 77 deletions(-) create mode 100644 .github/scripts/__pycache__/pr-gate.cpython-313.pyc create mode 100644 e2e/lab/__pycache__/common.cpython-313.pyc create mode 100644 e2e/lab/__pycache__/coordinated.cpython-313.pyc create mode 100644 e2e/lab/__pycache__/lab.cpython-313.pyc create mode 100644 e2e/lab/__pycache__/test_coordinated.cpython-313.pyc create mode 100644 e2e/lab/__pycache__/test_lab.cpython-313.pyc create mode 100644 e2e/lab/__pycache__/test_mac.cpython-313.pyc create mode 100644 e2e/lab/__pycache__/test_orchestration.cpython-313.pyc create mode 100644 e2e/lab/platforms/__pycache__/_mac.cpython-313.pyc create mode 100644 e2e/scenarios/share-self-view/README.md create mode 100644 e2e/scenarios/share-self-view/drive.linux.sh create mode 100644 e2e/scenarios/share-self-view/drive.macos.sh create mode 100644 e2e/scenarios/share-self-view/drive.py create mode 100644 e2e/scenarios/share-self-view/drive.windows.ps1 create mode 100644 e2e/scenarios/share-self-view/scenario.json diff --git a/.github/scripts/__pycache__/pr-gate.cpython-313.pyc b/.github/scripts/__pycache__/pr-gate.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a49adf24ecf1bf37daf29f163c71eb9e903ef1ab GIT binary patch literal 15001 zcma)jdr%xlnrBsY^}Cy}p(jVLZtdFRUc1-t9#Jx1&tJPf zqGaJ(3H@%sz85IRgE#Poy$0=Geyq*j%2^p?sb~=D@P48!;GgS;Dt{0j)>ftC=ZL=a3Cty zC|qzv42*LlfzhF6E))?JE;*)Bq#yo7l! za@zc2f1z$AD2K*r3*^7>tI2 z0%YF?ASEbr*$qN7fi>>Xn?D|flB1KH5|~u90YP%2Vc`38V?Ns#xS+b?jL#Q$;;bk^ zQ3}Z6h!QX84|wCdy!+3muRg!`d|fatK*%ygfoOp9K?0Ijss2o!KpmuONfC+)?Vu=* z>SxlAR1d4)tzCO`(Yp4E>bK|*C_Hsx1%iv+&oGok_Y*;lWqKTX$+hctN}zS&pfEfL zYo6Mhrh%iXsY26I4d?_xLLD@0qlRdYu}d|;h{Ua#<^HuX79H|F@g}WW zL@5{v!5n$aDjNZAQkjUNvg3j1h{|4yge8^j>F(}@dyo<;I~sxY&B#cxN)IVW2gj*> zt<3|1BFf6ZaAb5eHa5@(Og^DKNyjQ!oxBumvT6jgOE&7t5)Z9XgTM=D}y(OZw%iY zy)pXpJ+}%M?Wv*zA57e}b|?7WRagG(VB0pdINLbaOmUV6xdlpOWT0ko-TUD1qw1Z#En}BQW}8>5~+I zwgs9uc%2kXzQFJ-xnsIV9#Mz!k#(3db(qt29PML}eBMGdlGc(nQ_7Yu)s!w}&no43 zs1zsA{TUYTF>UA?JZ`77di1f_Si?7r7>sBqj9OOxnMJbJ&UT7-3bYsdlY^<=PBrCm zb$J+-l9B)7hPt}OxTW@Rv#+kvbNCCKhB#AK2a=%f3oM}0b#Y_=g~s!BU%-UI$g)i4TdZv$B)N0kX+MU|07)g&sxz__TIgORauP7TIcX+WY8at_+@ceyed~=9-PXjkW5i4&b$|nPPMMs>@NrBYF-*m*~(Vz zdCT^#N&D7$apCl`y(Vd|S#h}Lnv;&L)2%BG=bU@y=uFFsvtZe|E$Q60z%B%qowZ44 zEtc9db7Fm=nRD|^DQ5-d?VIU(WZvU5omqLGIb5$ic60v^_s^ew?OZCqHtDF%&K?E$!6vf^bUw8={YBQyGF|HyBUaUfRe^;?9ippXOkah?mQQtT!{w8;Br{TSvxV5p z=uKRqUNv%5XC+11p{`+SpJ9l8lLmGoGo~8H0@2_IOg7`&rPAX>(xvBlN}FfvfniYs z#Va3D%Sd6+#s@|t!N90;$d}1`9LQCwA^Gzc)D)G-IrMJdBK`7n^QTj;ZOg75N!N~r z(6XyO;i`YP?<)m+`Q4g2+C!^`fHbK~SWBAW6e4IZrWwtgZdGoCuW$sF0&E8aqCICR z=g>QSshmS8`=JDTNJawI%?z$GGBX2kqYdO4MqwH$g@GY0gCWh5a($INjnd>H35Kh; z1f&>qis{^<4WzookD5sF(4@04Ek`(NBuVdmwi| zmZ*Vbiuzy0TT=F;Ka9;){`}ajmPAu)vaxNsx_!3gMl5MRnqZH9b=Q7W!SVTiv4>qS zdDwLWXN3$ha69Ss7J|;g5+l%?aUM_a$_$`n0KrcLbPtZ}hC{CjCgMCr5v9}KpRp(U zXnh(W|2RyPsUK+~N1v$Y=}IPqQ&b27cCAcsGwKAkF+<(PIs#b7KAh$rRF@kLfz?+O z2kWS_Ut@z#zjhUX89avgVPpZ_%+##V^$Yg>08=NE_4sk`m&A~b6#scF$)vbT* z7q13KVsCGt`G??C;*d;HpF3PHwNJILxbkKvW+oEFb+?YB zT#Zv5D;1Rs^~nm~a>brx#h#BV9#2}zrY)=P^7;0U-8IuKtFEHCXO~@7DOc6o#}-@O zzxK|x4?6A)ruLm)Zs+rE1?%Hf_msjX~a z#ms?(69&BiH(ZJxB#rZuPt;zaM=knzSECum>I%X=s>`j<3MYU()e!?qasR zO-v64Qz3gmH!+2>>fFST@xtWjc0b4oMqi}?uxK}5T>xsNC%2m7ambDF$8as7bmV}G zMVY%;RYlxwu-z{h*Z3a!+#F-Q^AO}a}3e0GQM5Q}bzwDW2Y(v=PvKkURK>1j-mXMbcQUU#aave9`^@s${^Z&I zr3)9AFAOH(|LkDO5}a!J*V3}--Lv~<_RZ~nsX4)JUtl14ml@S`_&N zSU1@5a9Q-9Ktx&aX=5SACqn<4ckODHMXD z4nKX5qK$s~EBFFlDY&YCQ(k+-W?85BbKo`MEZYXo5;FdXMD=3{atI( zHIqR9YF&;Y+x}Wp=KUFk+@FCAHp64LQ~l_hkOTZoxb}m;svU$+jpSW6^(LK;%rz~D zbY9}kJ`_lnuDIhYLQ`plt{S70W}izt?S23l4vAu%`# zHeg7#W*{1mjVJ*kHdG@~4}>%1Zumle0u!QC%*cR&(NWdGx3+h+^c?T@w;k_Mnd5C> zGNWiBnm!FnX!_eW9*`B$k2**WK#6DIRGx(dnXPobI%VHB)%JOA@jN>(rEmJ!NR`RuBF@!s|DrrZ3{!M*QW}6tA*u%-THIp4cp(?-ac@Fk;bnb>RK~s(#LN55}5Z?el9ki0JT{gB#T!hX?x6Bvy=5Fjy zrJzYCT<#1=_%i`TVVl*ZL;$KS?qcjZuEVv7j$H%omlmv98G>o8ptsEN_8z7XU0J1MaE*8o{ z>%rv#MS0mLp931cKyMz-Mum&u_Y*9?`e8{fx z5s9mrcp<1Y-q}h*G2+!gFbZ&bL;{Nvq&CnmLL5g18i&GHp%0=w)Bq^_5EP5Z4Ittp zn1>F#=Shg0fC0+w2>H4Q{-(0{K3?C86+vh5i5rB#1sbEF@X%0NLqHe`obzUGhvNI1 zf!eW~GTP0mUGwyb{*V!vP%XML%HLOH^>#!$usnBzLfHbYco?x*>+&yU_ z0GXL%%~&K$jOt~yYg5K}OXE)HMt&Nmy1^dqcM!(Jq$phJ*9AvXaH1+@VnTZ%Aam|ZOi)&9~u%n+m=h)6Q%9H zi>1LQPXislz^6wRha6@Shb1h*JmRdvL~3C#eNefv$Q20uAz(_TTH{R!>Bu-GFr}Ca zRgB;wki-e!*A@&cfqBrVn$uAm)u~NA0Q~6Lcl)(ina(0FId5NQRF(T*8p8mjf8OdGQ3bg$x;L{$V#5ltPhJmL-KP_2;?`V{1MpZ z&)^a{!Q@Cew@)2iak-~DR_%pzV#;0#wusp_{rKF@nL{aa*?dpRylusjJL{TpB}xKI zmcdn$TQhSwWiFq8Hf840x$|X-9nqzU_&ticMjv6|(#kx|e2GsdmZ2!G%B0y|h|bvQ#4cw^*t~SS}P& zg+itv^wrmeJwDC!V)uQ$_)sY@f21h)8RknXRZ#P#gKF5bKs+544hJEEYi{?7+hoq`pwO{TSWJ3+3Y zTol%#uCTfuQG3qXcUhQ9GnQ|pc-Lu~1f@ssgs&lN!W0JqN$mahoG*wTbHhxJq;@D zi!)v>ZfL&R9Je-41Y`-MZ*$y$^|5tz&0Ku1murT-0a4LUTyXzbK)&1zxRPdT5Ys`I zo3NV!HhKUWt01a}reVC~8h1+HHE@mVAsZ=BzF&(wuW??lmrJK{<{D4|PjQC3rqUPX z2!3t6NIKSnok27U1SzNOI{=L_F(QI~hs_a_8N?WOK)~JxP(Rw14cIR-3>zaP(BwAI zmE%w+(F~wBP*2NIOu%8GF7xwW3)d~ecTnP4lwx^JZ12M8wek9EbZUK6UW%zOl)21Z8B1%uuou5=6RS8xB zd{TtyqB#h0C-7`=4u``M5p5Xg*NjkuJO)(6t!S+hD=%)xTUi_x1Bw_g0aE0c0-z{Y zi^2=85Wd=>cvN#tx-3N|BzY3P2l<3%DKY4Q--rbnQ^24_mr9WdQ{c3L*wMs|GhM5n z*qZWdkcX!-0Lc{fnKOU(9K`soU^2okfQ7+jhd1f)-Wpz%Q;udZIn2)KaME0|Y_3Y0 zs}j{Gm(86?bLYoBeTnmfsq^D2F3&At*?V{~oOC^vuspS5ch7+pnPAH_jzUuO1A!63 zQNM#(%Lb)*TF^8l#5#%Q&UiJFVJ#BBu@rA;0>}sWB;AI@3h4S9&zKZLI`9lSIU?j^ zR3F4jWQaE*ADlAiAb_ruC9`CdOoD+oW4^{Ml4T7V(*;E%HU8!%^jOn&hi%Q$*~p8H zNW*F1dAnfe?bwQ7McyUxRN!C1x*4dem(_JWM+vsg1esoL4an_#ceB_k?|3*WyAG=1 z(^is!cOs1&d%@@Q#R0kin3lj52FWBD!QOCneQlCO;MvBwxe@p6!HubrM9bqguXj8E zYXR{Fv)8MP#^iByk6>#IIN2(T5g%|vM*?wcBL?nZvu9(xs8L&=qH-7@0|?a*iwAe_ z+9kgVG^sXNlm0Zfqx2)I%wy8zB7t<#G}M$hGP>r)IY2i9iKUESUcI7 zHY^gSSc~lb1e;o-pP4x@AN|N)wc^N~?U?D9J3TjfV_?aVafVLMPrf$r_QBike>nE*V;`JM^z^0< z2&wuri7jV8cJzG-?!;;Oo&|Q}Ob^X8FWbxK^X7$H!GwKxg5CYq0~h5ypdeTLvbc4d zX1v**S0HDFXoC`Fn3xVDPyS)+V!_XuMUnYL)?1%{H4Q`Kx@O{>fU;wI+5wwl8 zkf&RUnmI>QDsEYYPl?rrpAUk}To0?Dz6Pa0J%~echJ{je&fc-VbhSlEz;a2{}>9!ZNShV`9Z-n5*Q|) zzaAqx3_#ey-lHB?V_gC}{1tqt=Cwj7LJXbK?1Xk%j$q&mApv;-6XZ<|wV9gIWV|Vj zM3n0T=MO~Jup2FN5x;sI5&#MAF|4%|81ln{f4P!%Mq}wc2j$3{>eMs^NW;vL@mV{-3dz)l zzW^{P=zJ2k0N)U{4P|Wy++-3rgZ$UR7+ErK7f$v6Z&xjNh%6YSM)))B|BHXjkm;8J zHg1|p*rF>NHt*Y|X(b2?r~4g)kr{6vAMP*IN3E|wF!mQ`p7!Z>mSEb8%NC9pT*qfP z=mluEQtchI0(O;l^lZ`Z)~;akTJCw_)QLS|PiVZCR~xdJSt= zXw9a#qUj(lNFv#JFt@XJC})Kf3}@||jLRk?Avv-~t8ZY#$b2&X?^14ml}-)psUqPQ zogT^EzeCUK+uHXN!6oDh?!D-+z#-+Wji`{Pe*^pi^Q0Y{ZFSw0_Z|wu1Yp_z#p6wa zLcE)dxB>Qo+rVb1(P>z_X4ANFZ23GXUvPrO0&Iymj8q^M3I&2YgSq6xx+;*0)_Tkr z3Pl9#C=v?DwNNM|mRuGFBjjhTC147$X3}*^`M4j9;4}FdYaiO>X>hWv-?SI~7~N&m zcB4Ofzk1h5dcS&cmlm?P4x^yD(?0;|X+PD?AMfq%c?LFhp<6{{n#$r1^0>+CCHvEz zXsnzCM7n!I66H7xub++Q_}0Dc1BrWVW4TU-0NiHyraMscJ%P!+=V zUh+d5`E`7iLm(1=242WdQ_J_ZpYroUXJ<>#Gb$Z8sv2R_1UMY#G$a#enw#S;E*g%G ziU-s959cW$TioSxY!OAPY8Is{VL2jct^_I_`9EMXiwSW>(Uu|DGLhT}OT+J9(hh1U zHa4!v7A%p22{F2U0C%c!LIwoLQ%routdgn4Mrzs6;T~3?bpB+R1Kv2 zM44!)%eU}d25^zTgO51CstJE60vkQPhi|@*Z;Ye(>i`AUeYTmFb+0K)b}RtC*@sZ< z*KjHy(V7Qc_>vdQtkNy>y+1BpIQ`?T)1kTD*N1N%n>vOY$C_uFXAjLBN|bq1cHf^U z#Mp!l`omJ#m9k}CO1izb zMw0G*(Zy*o)&+Lel{eRvCbX6uXb7ve8| z`-N{Oit3lm4M}sus?+_-_M3G#>JnQYOXf8#@*nKG>pXGiS=e_zdu-;|T-(c?Kv&L5 z`ZH(V)X_9#H62_j-?s2Xs=WS&d9ifb_^HMDmhh{#zpH}%%}bWUEAHZDcm4dHg(s5b z_18^cs1{ZH(L%Y4r@=DaI^P1xpDMAhA6uXL`cHXS`$x_bUn^*hezO(HU}%?!$< zqWw(84Es@VLn%QDRdXmT6ORV!MehdcMO2=I+~kXR2Y53jqjDkJNVQlL2|BgoyOWso zViLdvqdEj1)I<{TW5|+38;bBQb^sd$f>|)|qVnHk&VR&+S zjcW@>-Z=L9u{XM3?_TUkRUf<^{h&8h{B+8EVv1dHRZKZnj9aFdKbRPL%Y9oOU30&V zrVrn@F!V9{zRgOz@0ZZ@!TS~iU3K5V(0+JnrcL(?w$Tmu+h_;9{eA^Q@40U?(&hJa zZS-UJ%Pe%>{i3aO#l5F!igirKQ-;zN*8F0}cRFTz=c;bj-l%=)!bj|udj=|vH2gpC C2!`eW literal 0 HcmV?d00001 diff --git a/crates/chatd/src/media.rs b/crates/chatd/src/media.rs index 8a5aed1f..4674857c 100644 --- a/crates/chatd/src/media.rs +++ b/crates/chatd/src/media.rs @@ -230,6 +230,7 @@ fn new_call(conversation: Key, state: CallState) -> Live { security: None, picture: None, self_view: None, + share_view: None, }; Live { intent: NEXT_INTENT.fetch_add(1, Ordering::Relaxed), @@ -415,12 +416,14 @@ impl Live { } self.call.picture = picture; } - MediaResponse::SelfView { path, width, height, generation } => { - let picture = (!path.is_empty()).then(|| CallPicture { path, width, height, generation, user_id: String::new(), kind: PictureKind::Camera }); - if self.call.self_view == picture { + MediaResponse::SelfView { path, width, height, generation, share } => { + let kind = if share { PictureKind::Share } else { PictureKind::Camera }; + let picture = (!path.is_empty()).then(|| CallPicture { path, width, height, generation, user_id: String::new(), kind }); + let slot = if share { &mut self.call.share_view } else { &mut self.call.self_view }; + if *slot == picture { return false; } - self.call.self_view = picture; + *slot = picture; } MediaResponse::Sending { share, camera } => { let mut video: Vec = self.call.video.iter().filter(|stream| stream.direction != Direction::Encode).cloned().collect(); @@ -430,7 +433,9 @@ impl Live { if share { video.insert(0, VideoStream { direction: Direction::Encode, content: Content::Share, source: String::new() }); } - if video == self.call.video { + // My preview of a share that is no longer sent goes with it. + let dropped = !share && self.call.share_view.take().is_some(); + if video == self.call.video && !dropped { return false; } self.call.video = video; @@ -1741,6 +1746,34 @@ mod tests { } } + #[test] + fn my_camera_and_my_share_keep_their_own_self_views() { + let view = |path: &str, generation: u64, share: bool| MediaResponse::SelfView { path: path.into(), width: 640, height: 360, generation, share }; + let mut live = live(CallState::Joined); + assert!(live.apply(view("camera.jpg", 1, false))); + assert!(live.apply(view("share.jpg", 1, true))); + let camera = live.call.self_view.clone().unwrap(); + let share = live.call.share_view.clone().unwrap(); + assert_eq!((camera.path.as_str(), camera.kind), ("camera.jpg", PictureKind::Camera)); + assert_eq!((share.path.as_str(), share.kind), ("share.jpg", PictureKind::Share)); + assert!(!live.apply(view("share.jpg", 1, true)), "the same picture is no news"); + + // The share going off takes only its own view. + assert!(live.apply(view("", 0, true))); + assert!(live.call.share_view.is_none()); + assert!(live.call.self_view.is_some(), "the camera is still on"); + } + + #[test] + fn a_share_that_is_no_longer_sent_takes_its_view_with_it() { + let mut live = live(CallState::Joined); + assert!(live.apply(MediaResponse::SelfView { path: "share.jpg".into(), width: 640, height: 360, generation: 1, share: true })); + live.apply(MediaResponse::Sending { share: true, camera: false }); + assert!(live.call.share_view.is_some(), "still sending"); + assert!(live.apply(MediaResponse::Sending { share: false, camera: false })); + assert!(live.call.share_view.is_none()); + } + #[test] fn only_the_voice_connection_being_up_makes_a_call_joined() { let mut live = live(CallState::Connecting); diff --git a/crates/mediad/src/discord_video.rs b/crates/mediad/src/discord_video.rs index 7c132ac5..2772e2e7 100644 --- a/crates/mediad/src/discord_video.rs +++ b/crates/mediad/src/discord_video.rs @@ -241,15 +241,16 @@ impl Drive { match word { Word::Frame { payload, rtp, .. } => self.send_frame(dave, socket, rtp as u32, &payload), Word::Failed { words, .. } => out::send(&MediaResponse::Notice { detail: words }), - // The camera thread paints my own tile. A screen leg has no camera, so it sends none. - Word::SelfView(painted) => out::send(&match painted { + // The capture thread paints my own tile: my screen, from a screen leg. + Word::SelfView { share, painted } => out::send(&match painted { Some(painted) => MediaResponse::SelfView { path: painted.path.display().to_string(), width: painted.width, height: painted.height, generation: painted.generation, + share, }, - None => MediaResponse::SelfView { path: String::new(), width: 0, height: 0, generation: 0 }, + None => MediaResponse::SelfView { path: String::new(), width: 0, height: 0, generation: 0, share }, }), } } diff --git a/crates/mediad/src/picture/desktop.rs b/crates/mediad/src/picture/desktop.rs index e0260fad..f321472e 100644 --- a/crates/mediad/src/picture/desktop.rs +++ b/crates/mediad/src/picture/desktop.rs @@ -131,11 +131,47 @@ pub struct Outgoing { camera: Camera, cost: Cost, camera_cost: GrabCost, - /// My own camera, painted for me (`selfie`). - selfie_canvas: Canvas, - selfie_at: Option, - selfie_generation: u64, - selfie_painted: Option, + /// My own camera, painted for me. + selfie: Selfie, + /// My own share, painted for me. Apart from the camera's: both can be on at once. + screen_selfie: Selfie, +} + +/// One of my own pictures shrunk and written as a JPEG a few times a second, for my own tile. +#[derive(Default)] +struct Selfie { + canvas: Canvas, + at: Option, + generation: u64, + painted: Option, +} + +impl Selfie { + /// Paints this grab, unless the last was painted less than [`super::SELF_VIEW_EVERY`] ago. + fn shoot(&mut self, grabbed: &Rgba) { + if self.at.is_some_and(|at| at.elapsed() < super::SELF_VIEW_EVERY) { + return; + } + self.at = Some(Instant::now()); + let (width, height) = fit(grabbed.width, grabbed.height, super::SELF_VIEW.0, super::SELF_VIEW.1); + let rgb = super::screens::shrink(grabbed, width, height); + self.generation = self.generation.wrapping_add(1); + if let Some(painted) = self.canvas.paint(&rgb, width, height, self.generation) { + self.painted = Some(painted); + } + } + + /// The last picture painted and not yet taken. + fn take(&mut self) -> Option { + self.painted.take() + } + + /// The picture's file goes, and the next shot is due at once. + fn forget(&mut self) { + self.canvas.forget(); + self.painted = None; + self.at = None; + } } /// What a camera frame costs to read, in the log once a second or so, with the rate the camera @@ -209,29 +245,22 @@ impl Outgoing { let (width, height) = fit(grabbed.width, grabbed.height, quality.max.0, quality.max.1); let planes = i420(&grabbed.pixels, grabbed.width, grabbed.height, width, height, grabbed.bgra); let converted = Instant::now(); + // The grab is the whole screen, so the preview costs one shrink a tenth of a second. + self.screen_selfie.shoot(&grabbed); let encoded = coded(&mut self.share, width, height, quality.bps, quality.fps as f32, true)?.encode(&planes, &ask); self.cost.note(began, captured, converted, Instant::now(), (grabbed.width, grabbed.height), (width, height)); encoded } - /// My own camera for my own tile, a few times a second: the grab shrunk and written as a - /// JPEG, taken by [`Outgoing::self_view`]. - fn selfie(&mut self, grabbed: &Rgba) { - if self.selfie_at.is_some_and(|at| at.elapsed() < super::SELF_VIEW_EVERY) { - return; - } - self.selfie_at = Some(Instant::now()); - let (width, height) = fit(grabbed.width, grabbed.height, super::SELF_VIEW.0, super::SELF_VIEW.1); - let rgb = super::screens::shrink(grabbed, width, height); - self.selfie_generation = self.selfie_generation.wrapping_add(1); - if let Some(painted) = self.selfie_canvas.paint(&rgb, width, height, self.selfie_generation) { - self.selfie_painted = Some(painted); - } + /// My own camera as painted for me since last asked: a few times a second, the camera's + /// grab shrunk and written as a JPEG. + pub fn self_view(&mut self) -> Option { + self.selfie.take() } - /// The last self view painted and not yet taken. - pub fn self_view(&mut self) -> Option { - self.selfie_painted.take() + /// My own share as painted for me since last asked, on the same terms as [`Outgoing::self_view`]. + pub fn share_view(&mut self) -> Option { + self.screen_selfie.take() } /// The camera's two layers, high then low, or why the camera could not be read. A layer with @@ -243,7 +272,7 @@ impl Outgoing { let began = Instant::now(); let grabbed = self.camera.frame()?; self.camera_cost.note(began.elapsed(), (grabbed.width, grabbed.height)); - self.selfie(&grabbed); + self.selfie.shoot(&grabbed); let layer = |slot: &mut Option, ask: Option, most: (u32, u32), nominal: u32| match ask { Some(ask) => { let (width, height) = fit(grabbed.width, grabbed.height, most.0, most.1); @@ -259,14 +288,13 @@ impl Outgoing { pub fn close_camera(&mut self) { self.camera.close(); - self.selfie_canvas.forget(); - self.selfie_painted = None; - self.selfie_at = None; + self.selfie.forget(); } /// The share is off. Drop the encoder, and on Linux close the portal session so the recording indicator does not stay up. pub fn close_share(&mut self) { self.share = None; + self.screen_selfie.forget(); #[cfg(all(target_os = "linux", not(target_env = "ohos")))] super::portal::stop_screen(); } @@ -939,6 +967,33 @@ pub fn probe_camera() -> Result<(), String> { mod tests { use super::*; + fn screen() -> Rgba { + Rgba { width: 1920, height: 1080, pixels: vec![200; 1920 * 1080 * 4], bgra: true } + } + + #[test] + fn a_self_view_is_shrunk_to_the_corner_size_painted_at_a_steady_rate_and_let_go() { + let mut outgoing = Outgoing::default(); + outgoing.screen_selfie.shoot(&screen()); + let first = outgoing.share_view().expect("the first grab is painted at once"); + assert_eq!((first.width, first.height), super::super::SELF_VIEW); + assert!(first.path.exists()); + assert!(outgoing.share_view().is_none(), "taken once"); + assert!(outgoing.self_view().is_none(), "the camera's slot is a different one"); + + outgoing.screen_selfie.shoot(&screen()); + assert!(outgoing.share_view().is_none(), "a grab inside the interval is not painted"); + + outgoing.screen_selfie.at = None; + outgoing.screen_selfie.shoot(&screen()); + let next = outgoing.share_view().unwrap(); + assert_ne!(next.generation, first.generation); + assert!(!first.path.exists(), "the file before it is gone"); + + outgoing.screen_selfie.forget(); + assert!(!next.path.exists(), "and so is the last one when the share stops"); + } + #[test] fn openh264_is_fetched_from_cisco() { let name = library_name().unwrap_or("openh264-2.6.0-win64.dll"); diff --git a/crates/mediad/src/picture/phone.rs b/crates/mediad/src/picture/phone.rs index bd3e0eed..eb746ec6 100644 --- a/crates/mediad/src/picture/phone.rs +++ b/crates/mediad/src/picture/phone.rs @@ -130,6 +130,16 @@ impl Outgoing { Ok((high, low)) } + /// A phone paints no preview of its own camera or share for its call screen, so `Source` has + /// nothing to take from it. + pub fn self_view(&mut self) -> Option { + None + } + + pub fn share_view(&mut self) -> Option { + None + } + /// The button is off: a phone's camera light goes off with it. pub fn close_camera(&mut self) { self.camera = None; diff --git a/crates/mediad/src/tiny.rs b/crates/mediad/src/tiny.rs index 26f8b125..52c9d571 100644 --- a/crates/mediad/src/tiny.rs +++ b/crates/mediad/src/tiny.rs @@ -1047,9 +1047,9 @@ impl Call { out::send(&MediaResponse::Sending { share: false, camera: self.sending_camera }); } } - Word::SelfView(painted) => out::send(&match painted { - Some(painted) => MediaResponse::SelfView { path: painted.path.display().to_string(), width: painted.width, height: painted.height, generation: painted.generation }, - None => MediaResponse::SelfView { path: String::new(), width: 0, height: 0, generation: 0 }, + Word::SelfView { share, painted } => out::send(&match painted { + Some(painted) => MediaResponse::SelfView { path: painted.path.display().to_string(), width: painted.width, height: painted.height, generation: painted.generation, share }, + None => MediaResponse::SelfView { path: String::new(), width: 0, height: 0, generation: 0, share }, }), Word::Failed { share: false, words } => { if !self.camera_noted { diff --git a/crates/mediad/src/video.rs b/crates/mediad/src/video.rs index f88de56f..14bd6dec 100644 --- a/crates/mediad/src/video.rs +++ b/crates/mediad/src/video.rs @@ -251,8 +251,8 @@ pub enum Word { }, /// The share or the camera cannot go on, in words. Failed { share: bool, words: String }, - /// My own camera, painted for my tile; `None` when the camera went off. - SelfView(Option), + /// My own camera, or with `share` my own share, painted for my tile; `None` when it went off. + SelfView { share: bool, painted: Option }, } /// The RTP time at 90 kHz of a capture `since` the first one. @@ -382,6 +382,10 @@ pub trait Source { fn self_view(&mut self) -> Option { None } + /// My own share painted for me since last asked, on the same terms. + fn share_view(&mut self) -> Option { + None + } } impl Source for Outgoing { @@ -389,6 +393,10 @@ impl Source for Outgoing { Outgoing::self_view(self) } + fn share_view(&mut self) -> Option { + Outgoing::share_view(self) + } + fn share(&mut self, ask: Ask) -> Result { Outgoing::share(self, ask) } @@ -526,6 +534,11 @@ impl Capture { return false; } } + if let Some(painted) = self.source.share_view() { + if self.tell.send(Word::SelfView { share: true, painted: Some(painted) }).is_err() { + return false; + } + } } if wants.camera { let high = self.ask(Track::High, wants.rates.high, since, at, fps); @@ -537,13 +550,11 @@ impl Capture { { return false; } - if wants.camera { - if let Some(painted) = self.source.self_view() { - if self.tell.send(Word::SelfView(Some(painted))).is_err() { - return false; - } - } - } + if let Some(painted) = self.source.self_view() { + if self.tell.send(Word::SelfView { share: false, painted: Some(painted) }).is_err() { + return false; + } + } } Err(words) => { if let Some(ask) = high { @@ -633,10 +644,11 @@ fn capture(mut work: Capture, orders: &Orders) { work.source.close_camera(); } if seen.camera && !wants.camera { - let _ = work.tell.send(Word::SelfView(None)); + let _ = work.tell.send(Word::SelfView { share: false, painted: None }); } if seen.share && !wants.share { work.source.close_share(); + let _ = work.tell.send(Word::SelfView { share: true, painted: None }); } schedule.rate(&wants); seen = wants; @@ -1395,6 +1407,12 @@ mod tests { skip_next: bool, refuse: Option, closed: u32, + /// Paints a picture of my camera and of my share with every round, as a desktop does. + painting: bool, + } + + fn painted(name: &str) -> Painted { + Painted { path: std::path::PathBuf::from(name), width: 4, height: 2, generation: 1 } } fn coded(ask: Ask, name: u8) -> Encoded { @@ -1430,6 +1448,14 @@ mod tests { fn close_camera(&mut self) { self.closed += 1; } + + fn self_view(&mut self) -> Option { + self.painting.then(|| painted("camera.jpg")) + } + + fn share_view(&mut self) -> Option { + self.painting.then(|| painted("share.jpg")) + } } fn work(controls: Arc) -> (Capture, Receiver) { @@ -1493,6 +1519,76 @@ mod tests { ); } + fn views(words: &Receiver) -> Vec<(bool, Option)> { + words + .try_iter() + .filter_map(|word| match word { + Word::SelfView { share, painted } => Some((share, painted.map(|painted| painted.path.display().to_string()))), + _ => None, + }) + .collect() + } + + #[test] + fn my_share_and_my_camera_are_painted_for_me_apart_when_both_are_on() { + let (mut capture, words) = work(Arc::default()); + capture.source.painting = true; + assert!(capture.round(&wanting(true, true), Instant::now(), 15.)); + assert_eq!( + views(&words), + [(true, Some("share.jpg".to_owned())), (false, Some("camera.jpg".to_owned()))], + "one slot each, so neither clobbers the other" + ); + } + + #[test] + fn only_what_is_on_is_painted_for_me() { + let (mut capture, words) = work(Arc::default()); + capture.source.painting = true; + assert!(capture.round(&wanting(true, false), Instant::now(), 15.)); + assert_eq!(views(&words), [(true, Some("share.jpg".to_owned()))], "a share alone has no camera view"); + assert!(capture.round(&wanting(false, true), Instant::now(), 15.)); + assert_eq!(views(&words), [(false, Some("camera.jpg".to_owned()))], "a camera alone has no share view"); + } + + #[test] + fn the_capture_thread_takes_my_share_view_down_when_the_share_stops() { + struct Viewing(Fake); + impl Source for Viewing { + fn share(&mut self, ask: Ask) -> Result { + self.0.share(ask) + } + fn camera(&mut self, high: Option, low: Option) -> Result<(Encoded, Encoded), String> { + self.0.camera(high, low) + } + fn close_camera(&mut self) {} + fn share_view(&mut self) -> Option { + self.0.share_view() + } + } + let sender = start_capture(|| Viewing(Fake { painting: true, ..Fake::default() }), Arc::default()).unwrap(); + let tell = |wants: Wants| { + sender.orders.order.lock().unwrap().wants = wants; + sender.orders.changed.notify_all(); + }; + tell(wanting(true, false)); + let seen = |word: &Word| matches!(word, Word::SelfView { share: true, painted: Some(_) }); + loop { + let word = sender.words.recv_timeout(Duration::from_secs(5)).unwrap(); + if seen(&word) { + break; + } + } + tell(Wants::default()); + let mut cleared = false; + while let Ok(word) = sender.words.recv_timeout(Duration::from_millis(300)) { + cleared |= matches!(word, Word::SelfView { share: true, painted: None }); + } + assert!(cleared, "the tile is told my share is gone"); + sender.orders.order.lock().unwrap().stop = true; + sender.orders.changed.notify_all(); + } + #[test] fn a_frame_sealing_drops_asks_again_and_a_skipped_keyframe_is_still_owed() { let controls: Arc = Arc::default(); @@ -1947,7 +2043,7 @@ mod tests { bytes += payload.len(); } Some(Word::Failed { words, .. }) => panic!("{words}"), - Some(Word::SelfView(_)) => {} + Some(Word::SelfView { .. }) => {} None => std::thread::yield_now(), } } @@ -1956,6 +2052,45 @@ mod tests { video.stop(); } + /// What `e2e/scenarios/share-self-view` runs: my own share, painted for me from the real + /// screen through the real capture thread, and taken down when the share stops. + #[test] + #[ignore = "needs a screen and the OpenH264 binary"] + fn the_capture_thread_paints_my_own_share_from_a_real_screen() { + let mut video = Video::new(Arc::default()); + video.want(Wants { share: true, rates: Rates::default(), ..Wants::default() }); + let started = Instant::now(); + let mut shown = None; + while shown.is_none() && started.elapsed() < Duration::from_secs(20) { + match video.next() { + Some(Word::SelfView { share: true, painted: Some(painted) }) => shown = Some(painted), + Some(Word::SelfView { share: false, .. }) => panic!("the camera is off, so no camera view"), + Some(Word::Failed { words, .. }) => panic!("{words}"), + Some(_) => {} + None => std::thread::sleep(Duration::from_millis(5)), + } + } + let shown = shown.expect("my own share was never painted for me"); + let jpeg = std::fs::read(&shown.path).expect("the picture is on disk"); + let size = image::load_from_memory_with_format(&jpeg, image::ImageFormat::Jpeg).expect("a JPEG the window can read"); + assert_eq!((size.width(), size.height()), (shown.width, shown.height)); + assert!(shown.width <= picture::SELF_VIEW.0 && shown.height <= picture::SELF_VIEW.1, "{}x{}", shown.width, shown.height); + eprintln!("share-self-view-proof: {}x{} JPEG of the real screen, {} bytes", shown.width, shown.height, jpeg.len()); + video.want(Wants::default()); + let stopped = Instant::now(); + let mut cleared = false; + while !cleared && stopped.elapsed() < Duration::from_secs(10) { + match video.next() { + Some(Word::SelfView { share: true, painted: None }) => cleared = true, + Some(_) => {} + None => std::thread::sleep(Duration::from_millis(5)), + } + } + assert!(cleared, "the window is told my share is gone"); + eprintln!("share-self-view-proof: cleared when the share stopped"); + video.stop(); + } + #[test] fn a_resume_starts_no_new_thread_and_hang_up_ends_them_all() { let mut video = Video::new(Arc::default()); diff --git a/crates/protocol/src/call.rs b/crates/protocol/src/call.rs index 52c07ba8..91ab574c 100644 --- a/crates/protocol/src/call.rs +++ b/crates/protocol/src/call.rs @@ -245,6 +245,10 @@ pub struct Call { /// My own camera as it is sent, for my tile. `None` while it is off. Its `user_id` is empty. #[serde(default, skip_serializing_if = "Option::is_none")] pub self_view: Option, + /// My own share as it is sent, for the stage while I am sharing. `None` while it is off. Its + /// `user_id` is empty. Apart from `self_view`: a camera and a share can be on together. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub share_view: Option, } /// A Tiny server call's protection (tinyserver's `docs/calls.md`, "End-to-end encryption"). @@ -890,9 +894,16 @@ pub enum MediaResponse { }, /// What our camera and share are actually sending, after an answer or a refusal. Sending { share: bool, camera: bool }, - /// Our own camera as it is being sent, a few times a second, so the person sees what - /// everyone else sees; an empty path when the camera went off. - SelfView { path: String, width: u32, height: u32, generation: u64 }, + /// Our own camera, or with `share` our own share, as it is being sent, a few times a second, + /// so the person sees what everyone else sees; an empty path when it went off. + SelfView { + path: String, + width: u32, + height: u32, + generation: u64, + #[serde(default)] + share: bool, + }, /// A picture that could not be captured, in words. The voice call stays. Notice { detail: String }, } @@ -945,6 +956,16 @@ impl MediaResponse { mod tests { use super::*; + #[test] + fn a_self_view_is_my_camera_unless_it_says_it_is_my_share() { + // A mediad from before shares had a preview sends none: that is my camera, never an error. + let older: MediaResponse = serde_json::from_str(r#"{"media":"self_view","path":"a.jpg","width":640,"height":360,"generation":3}"#).unwrap(); + assert_eq!(older, MediaResponse::SelfView { path: "a.jpg".into(), width: 640, height: 360, generation: 3, share: false }); + let mine = MediaResponse::SelfView { path: "b.jpg".into(), width: 640, height: 360, generation: 4, share: true }; + let back: MediaResponse = serde_json::from_str(&serde_json::to_string(&mine).unwrap()).unwrap(); + assert_eq!(back, mine); + } + #[test] fn a_requirement_is_sent_only_when_it_is_made_and_read_as_off_when_absent() { // An older chatd or mediad does not send it: that is "not required", never an error. diff --git a/crates/tinyclient/src/gui/call.rs b/crates/tinyclient/src/gui/call.rs index c8ad1659..d5a18e8a 100644 --- a/crates/tinyclient/src/gui/call.rs +++ b/crates/tinyclient/src/gui/call.rs @@ -223,6 +223,8 @@ pub struct State { pub(in crate::gui) feed: super::tiny::feed::Feed>, /// The frames of my own camera, for my tile. pub(in crate::gui) self_feed: super::tiny::feed::Feed>, + /// The frames of my own share, for my stream's tile and the stage. + pub(in crate::gui) screen_feed: super::tiny::feed::Feed>, /// Made the first time the dock is drawn. counter: OnceCell>, /// The same count, for a Tiny channel's stage: a second text, ticking on its own. @@ -1001,6 +1003,7 @@ impl Shell { security: None, picture: None, self_view: None, + share_view: None, }); } } diff --git a/crates/tinyclient/src/gui/call/dock.rs b/crates/tinyclient/src/gui/call/dock.rs index 2ccbdf8c..8b18ffca 100644 --- a/crates/tinyclient/src/gui/call/dock.rs +++ b/crates/tinyclient/src/gui/call/dock.rs @@ -1286,6 +1286,7 @@ mod tests { security: None, picture: None, self_view: None, + share_view: None, } } diff --git a/crates/tinyclient/src/gui/call/phone/screens.rs b/crates/tinyclient/src/gui/call/phone/screens.rs index 2c290d6d..82eb1c12 100644 --- a/crates/tinyclient/src/gui/call/phone/screens.rs +++ b/crates/tinyclient/src/gui/call/phone/screens.rs @@ -223,6 +223,7 @@ mod tests { security: None, picture: None, self_view: None, + share_view: None, } } diff --git a/crates/tinyclient/src/gui/call/security.rs b/crates/tinyclient/src/gui/call/security.rs index 762c55e9..4101d9b3 100644 --- a/crates/tinyclient/src/gui/call/security.rs +++ b/crates/tinyclient/src/gui/call/security.rs @@ -585,6 +585,7 @@ mod tests { security: Some(security), picture: None, self_view: None, + share_view: None, } } diff --git a/crates/tinyclient/src/gui/call/shot.rs b/crates/tinyclient/src/gui/call/shot.rs index a3eb6d42..5d2aaa85 100644 --- a/crates/tinyclient/src/gui/call/shot.rs +++ b/crates/tinyclient/src/gui/call/shot.rs @@ -18,6 +18,9 @@ //! faces; `tiny_security` opens the security panel from the channel's top bar, //! `tiny_security_bar` from the column's compact bar. `tiny_poor`'s numbers carry audio trouble //! too, for the health hints. +//! +//! `tiny_sharing` is a call where I share my screen and mediad has painted the first picture of +//! it for my own tile (a made-up one, the demo's schematic); `--tiny-stream` focuses my stream. use super::phone::{Sheet, Shown}; use super::security::Place; @@ -198,6 +201,7 @@ pub(super) fn call(snapshot: &Snapshot) -> Option { // The open conversation's, so the header pill reads Leave or Cancel as it would. let conversation = snapshot.open.as_ref().map_or_else(|| key("shot"), |open| open.key.clone()); let muted = matches!(name.as_str(), "joined_muted" | "muted_talking"); + let sharing = name == "sharing"; let participants = if tiny() { // A Tiny stage draws the room's seats, not the call's roster. Vec::new() @@ -257,13 +261,23 @@ pub(super) fn call(snapshot: &Snapshot) -> Option { input: "MacBook Pro Microphone".to_owned(), output: "MacBook Pro Speakers".to_owned(), engine_linked: true, - video: Vec::new(), + video: sharing.then(|| protocol::VideoStream { direction: protocol::Direction::Encode, content: protocol::Content::Share, source: String::new() }).into_iter().collect(), security: None, picture: None, self_view: None, + share_view: sharing.then(screen_picture).flatten(), }) } +/// A made-up picture of my own screen, as mediad paints it for my tile: the demo's schematic +/// shrunk to the self-view size and written as a JPEG. +fn screen_picture() -> Option { + let shrunk = image::open(photo("schematic.webp")).ok()?.resize(640, 360, image::imageops::FilterType::Triangle).to_rgb8(); + let path = std::env::temp_dir().join("tinyclient-shot-screen.jpg"); + shrunk.save_with_format(&path, image::ImageFormat::Jpeg).ok()?; + Some(protocol::CallPicture { path: path.display().to_string(), width: shrunk.width(), height: shrunk.height(), generation: 1, user_id: String::new(), kind: protocol::PictureKind::Share }) +} + fn mara() -> Subject { Subject { title: "Mara Okafor".to_owned(), kind: ConversationKind::Direct, avatar: None, space: None } } @@ -384,6 +398,7 @@ fn bare(conversation: Key, state: CallState, participants: Vec, joi security: None, picture: None, self_view: None, + share_view: None, } } diff --git a/crates/tinyclient/src/gui/mod.rs b/crates/tinyclient/src/gui/mod.rs index 90a51cd1..549f8926 100644 --- a/crates/tinyclient/src/gui/mod.rs +++ b/crates/tinyclient/src/gui/mod.rs @@ -301,7 +301,8 @@ fn shell_bindings() -> Vec { /// `--autoplay always|hover|never` (when GIFs play), `--frames N` (N frames 150 ms apart, as /// `out-1.png` …, to see moving pictures move). On a Tiny server (`--mode tiny`): `--tiny-room /// N` (the Nth channel), `--tiny-menu header|channel|person:N` (N: the Nth seat, `:sub` adds its -/// Move submenu), `--tiny-modal invite|code|kick|ban|profile`, `--tiny-settings`, `--tiny-card N` +/// Move submenu), `--tiny-stream` (my own stream filling the stage, with `TINYCLIENT_SHOT_CALL=tiny_sharing`), +/// `--tiny-modal invite|code|kick|ban|profile`, `--tiny-settings`, `--tiny-card N` /// (the Nth member's hover card), `--tiny-setup first|custom|refused|checklist|links|privacy|change|change-anyway|member` (first-run /// setup, or Server Settings › Privacy, over a made-up outline), `--tiny-confirm transfer|codes`. /// diff --git a/crates/tinyclient/src/gui/shot_demo.rs b/crates/tinyclient/src/gui/shot_demo.rs index f3633360..0ef91076 100644 --- a/crates/tinyclient/src/gui/shot_demo.rs +++ b/crates/tinyclient/src/gui/shot_demo.rs @@ -939,6 +939,7 @@ fn demo_call(conversation: &protocol::Key) -> protocol::Call { security: None, picture: None, self_view: None, + share_view: None, } } diff --git a/crates/tinyclient/src/gui/shot_demo_live.rs b/crates/tinyclient/src/gui/shot_demo_live.rs index 4a57d577..05ff09e2 100644 --- a/crates/tinyclient/src/gui/shot_demo_live.rs +++ b/crates/tinyclient/src/gui/shot_demo_live.rs @@ -106,6 +106,7 @@ fn bare(conversation: Key, state: CallState, participants: Vec) -> security: None, picture: None, self_view: None, + share_view: None, } } diff --git a/crates/tinyclient/src/gui/tiny/channel.rs b/crates/tinyclient/src/gui/tiny/channel.rs index 634112ef..1e8df564 100644 --- a/crates/tinyclient/src/gui/tiny/channel.rs +++ b/crates/tinyclient/src/gui/tiny/channel.rs @@ -444,14 +444,16 @@ impl Shell { self.call_state.feed.shown().cloned() } - /// My own camera as it is sent, while it is on. - fn tiny_self_frame(&self, call: Option<&Call>) -> Option> { - call?.self_view.as_ref().filter(|picture| !picture.path.is_empty())?; - self.call_state.self_feed.shown().cloned() + /// My own camera, or with `share` my own screen, as it is sent, while it is on. + fn tiny_self_frame(&self, call: Option<&Call>, share: bool) -> Option> { + let (picture, feed) = if share { (call?.share_view.as_ref(), &self.call_state.screen_feed) } else { (call?.self_view.as_ref(), &self.call_state.self_feed) }; + picture.filter(|picture| !picture.path.is_empty())?; + feed.shown().cloned() } - /// What a stream shows: its picture; mine, which is never sent back to me, said in words with - /// Stop; anyone else's, "Watch stream" until its first picture arrives. + /// What a stream shows: its picture; mine, the same small live view of it that I send, with + /// Stop over it (until the first one lands, words with Stop); anyone else's, "Watch stream" + /// until its first picture arrives. fn tiny_stream_body(&self, page: &Page, stream: &Stream, call: Option<&Call>, size: Size, cx: &mut Context) -> AnyElement { if let Some(frame) = self.tiny_frame(call, &stream.user_id) { return img(frame).size_full().object_fit(ObjectFit::Contain).into_any_element(); @@ -459,25 +461,35 @@ impl Shell { let small = size == Size::Strip; let large = size == Size::Big; let body = div().size_full().relative().flex().flex_col().items_center().justify_center().gap(px(if small { 4. } else { 10. })).p(px(8.)); - if stream.mine && !stream.share { - // My camera as everyone sees it, with Stop over it. - if let Some(frame) = self.tiny_self_frame(call) { - let stop = button_with_icon("tiny-stream-camera-off", ButtonKind::Danger, "icons/video-off.svg", "Turn camera off").on_click(cx.listener(|this, _, _, cx| { - cx.stop_propagation(); - this.call_ask(Request::Media(MediaRequest::Camera { on: false }), cx); - })); + if stream.mine { + // My camera or my screen as everyone sees it, with Stop over it. + if let Some(frame) = self.tiny_self_frame(call, stream.share) { + let stop = if stream.share { + button_with_icon("tiny-stream-stop", ButtonKind::Danger, "icons/monitor-off.svg", "Stop sharing").on_click(cx.listener(|this, _, _, cx| { + cx.stop_propagation(); + this.tiny_stop_share(cx); + })) + } else { + button_with_icon("tiny-stream-camera-off", ButtonKind::Danger, "icons/video-off.svg", "Turn camera off").on_click(cx.listener(|this, _, _, cx| { + cx.stop_propagation(); + this.call_ask(Request::Media(MediaRequest::Camera { on: false }), cx); + })) + }; return div() .size_full() .relative() .child(img(frame).size_full().object_fit(ObjectFit::Contain)) .when(!small, |tile| { - tile.child(div().absolute().bottom(px(10.)).left_0().right_0().flex().justify_center().child(stop.h(px(28.)).on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation()))) + // A grid tile's caption sits at the bottom, so Stop goes along the top. + let row = div().absolute().left_0().right_0().flex().justify_center(); + let row = if size == Size::Grid { row.top(px(8.)) } else { row.bottom(px(10.)) }; + // On a picture that can be any colour, so it sits on the overlay as the strip's does. + tile.child(row.child(div().p(px(2.)).rounded(px(10.)).bg(theme::overlay()).child(stop.h(px(28.)).on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation())))) }) .into_any_element(); } } if stream.mine { - let thumbnail = self.tiny_state.shared.as_ref().filter(|_| stream.share).map(|screen| screen.thumbnail.clone()).filter(|path| !path.is_empty()); let words = if stream.share { "You're sharing your screen" } else { "Your camera is on" }; let stop = if stream.share { button_with_icon("tiny-stream-stop", ButtonKind::Danger, "icons/monitor-off.svg", "Stop sharing").on_click(cx.listener(|this, _, _, cx| { @@ -491,11 +503,10 @@ impl Shell { })) }; let line = match &self.tiny_state.shared { - Some(screen) if stream.share => format!("Everyone in the call can watch {}. It isn't played back to you, so you don't see a mirror of your own screen.", screen.name), + Some(screen) if stream.share => format!("Everyone in the call can watch {}. A live view of it shows here as soon as the first picture is sent.", screen.name), _ => "Everyone in the call can watch it.".to_owned(), }; return body - .children(thumbnail.map(|path| img(std::path::PathBuf::from(path)).absolute().top_0().left_0().size_full().object_fit(ObjectFit::Cover).opacity(0.3))) // A grid tile has room for the words and Stop, not the icon as well. .when(small || large, |body| body.child(glyph(if stream.share { "icons/monitor-up.svg" } else { "icons/video.svg" }, if small { 18. } else { 36. }, theme::accent_text()))) .when(!small, |body| body.child(div().text_center().whitespace_normal().type_ui().font_weight(theme::SEMIBOLD).text_color(theme::text()).child(words))) @@ -1127,6 +1138,7 @@ mod tests { security: None, picture: None, self_view: None, + share_view: None, } } @@ -1134,6 +1146,22 @@ mod tests { TinySeat { user_id: user_id.into(), ..TinySeat::default() } } + #[test] + fn my_camera_and_my_share_are_two_feeds_that_do_not_clobber_each_other() { + use super::super::feed::{named, Which}; + let picture = |path: &str, generation, kind| protocol::CallPicture { path: path.into(), width: 640, height: 360, generation, user_id: String::new(), kind }; + let mut call = joined(false, false, false); + let of = |call: &Call, which: fn(&Which) -> bool| named(Some(call)).into_iter().find(|(feed, _)| which(feed)).and_then(|(_, frame)| frame); + let (mine, screen): (fn(&Which) -> bool, fn(&Which) -> bool) = (|which| matches!(which, Which::Mine), |which| matches!(which, Which::Screen)); + assert_eq!((of(&call, mine), of(&call, screen)), (None, None)); + call.share_view = Some(picture("share.jpg", 7, protocol::PictureKind::Share)); + assert_eq!((of(&call, mine), of(&call, screen)), (None, Some((7, "share.jpg".to_owned()))), "a share alone leaves the camera's feed empty"); + call.self_view = Some(picture("camera.jpg", 2, protocol::PictureKind::Camera)); + assert_eq!((of(&call, mine), of(&call, screen)), (Some((2, "camera.jpg".to_owned())), Some((7, "share.jpg".to_owned())))); + call.share_view = None; + assert_eq!((of(&call, mine), of(&call, screen)), (Some((2, "camera.jpg".to_owned())), None), "the share stopping lets go of its feed only"); + } + #[test] fn my_tile_shows_my_call_at_once_and_others_light_on_the_quicker_edge() { let mine = as_heard(&seat("robin"), true, Some(&joined(true, false, false))); diff --git a/crates/tinyclient/src/gui/tiny/feed.rs b/crates/tinyclient/src/gui/tiny/feed.rs index 08cc1bbe..ecdfc45f 100644 --- a/crates/tinyclient/src/gui/tiny/feed.rs +++ b/crates/tinyclient/src/gui/tiny/feed.rs @@ -101,11 +101,22 @@ fn frame(path: &Path) -> Option> { Some(Arc::new(RenderImage::new(vec![image::Frame::new(pixels)]))) } -/// Which of the two feeds: the picture being watched, or my own camera. +/// Which of the three feeds: the picture being watched, my own camera, or my own share. #[derive(Clone, Copy)] pub(in crate::gui) enum Which { Watched, Mine, + Screen, +} + +/// The frame a call names for each feed: its generation and file. +pub(in crate::gui) fn named(call: Option<&Call>) -> [(Which, Option<(u64, String)>); 3] { + let frame = |picture: Option<&protocol::CallPicture>| picture.map(|picture| (picture.generation, picture.path.clone())); + [ + (Which::Watched, frame(call.and_then(|call| call.picture.as_ref()))), + (Which::Mine, frame(call.and_then(|call| call.self_view.as_ref()))), + (Which::Screen, frame(call.and_then(|call| call.share_view.as_ref()))), + ] } impl Shell { @@ -113,18 +124,13 @@ impl Shell { match which { Which::Watched => &mut self.call_state.feed, Which::Mine => &mut self.call_state.self_feed, + Which::Screen => &mut self.call_state.screen_feed, } } /// The call changed: the frames it names are read, and ones no longer named are let go. pub(in crate::gui) fn feed_follow(&mut self, call: Option<&Call>, cx: &mut Context) { - let watched = call - .and_then(|call| call.picture.as_ref()) - .map(|picture| (picture.generation, picture.path.clone())); - let mine = call - .and_then(|call| call.self_view.as_ref()) - .map(|picture| (picture.generation, picture.path.clone())); - for (which, picture) in [(Which::Watched, watched), (Which::Mine, mine)] { + for (which, picture) in named(call) { let (read, gone) = self.feed_of(which).offer(picture); if let Some(gone) = gone { cx.drop_image(gone, None); diff --git a/crates/tinyclient/src/gui/tiny/mod.rs b/crates/tinyclient/src/gui/tiny/mod.rs index b38fd888..d438f37d 100644 --- a/crates/tinyclient/src/gui/tiny/mod.rs +++ b/crates/tinyclient/src/gui/tiny/mod.rs @@ -1518,6 +1518,16 @@ impl Shell { let room = self.tiny_state.channel.as_ref().and_then(|id| community.rooms.iter().find(|room| room.id == *id)); self.tiny_state.focus = room.and_then(|room| room.participants.get(ix)).map(|seat| stage::Focus::Person(seat.user_id.clone())); } + // My own stream, filling the stage (a made-up call that has me sharing, `tiny_sharing`). + if std::env::args().any(|arg| arg == "--tiny-stream") { + self.tiny_state.focus = Some(stage::Focus::Stream(community.me.clone())); + } + // The picture mediad would have painted for my tile is read as a call's change reads it. + if std::env::var("TINYCLIENT_SHOT_CALL").is_ok_and(|name| name == "tiny_sharing") { + if let Some(call) = self.snapshot.as_ref().and_then(|snapshot| self.call_shown(snapshot)) { + self.feed_follow(Some(&call), cx); + } + } match flag("--tiny-menu").as_deref() { Some("header") => self.tiny_open_float(Float::Header, cx), Some("stats") => self.tiny_open_float(Float::Stats, cx), diff --git a/e2e/lab/__pycache__/common.cpython-313.pyc b/e2e/lab/__pycache__/common.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69471c7d7df6f36556f5b6d6be0d0466e4b24066 GIT binary patch literal 15747 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 literal 0 HcmV?d00001 diff --git a/e2e/lab/__pycache__/lab.cpython-313.pyc b/e2e/lab/__pycache__/lab.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a44c2c3791e8e052dfb08a67da1aa48211d6e4c GIT binary patch literal 36456 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 literal 0 HcmV?d00001 diff --git a/e2e/lab/__pycache__/test_coordinated.cpython-313.pyc b/e2e/lab/__pycache__/test_coordinated.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf3fa5207d0a06916c405e45744063f02b9c20eb GIT binary patch literal 31656 zcmeHw3vd)inr8J&U21jf{g!}60;2}CB;FuEMh{*F1gIpCEKIxAYKaD^Tdr#H(Cv6U zv$s29XZH+_^#Z%TKyxv%7BjvubK{F)BYZJna~}3$H>L|UZf%*}bL?*HtS>I^Z19|C zxr@8|{;aO9mMA@p?TgrmOTk}NSy`D`S(*R;{eS+M{mA8Va0tCWe{`yJC&&FAU1-6c zJbCmtCXRcZ6F89*OoDm8Ni?yeS+uaDRkX6BO|;=?*`M*8U9`K^w7kf(dzoS;J32%M zJ7$Sl?C2DoI9m5RpL2;WH+MX z0xx6=4k1f$)|&-ay{VoPvX7XAoVpCLyp*frgxqpY$UE-r*z{y+8!c*_Sjkf6BW1w? zDVH2yDik($bDTe)QoNEe8EV?xA4+U{I9m2SP(Zsn#8ixCcV#qN8HajVJnp(&=bq#O)6Rf|6AC31#2z zF)7x={^&_M4o3o~m8^hPNU+~yR%-l<3`$MkB7?Fs@D;;YR)6qJC=m2Y=fi==IcYWa zhDHLr75mvxxIc1MQfxz^@aVb64zD+OE*cE?-3Jwjh zT*n;Ivk~t|FfuX}94kpH&YLPNB90ZN-$)gap_oJcN@nm}FfbYoMZ$_*3=ReTQc%ep z8S+O5BI2;5xWwQ~qaiWa@AHd;sA)JD?3V)R{UA9YxJR!c_I2(!he6GWX2FC(Z7%09 zq%EK}!3vro*g)+<1}HDsK{Ev&)FEVoW(f{Zr;r8e5}csff(tZ9$Og?7azOK_i(|0m zfffkp#A2aP09qszf))!!pd~^vXsJ*lmJODA%9Mh%4%wRQkDm}H2xxVu_sPb88X}MW zHiP3%;7vNYj`aJK2B9}O@M)mxOrY1Q-sQLsJUu(;gQSxiN~J{pS+i4eR4V^uY=`s7 zIE{I@x!xS@?i^3&YWMY{_B3jgsm1mdYG)nA+L?arDAUiiv)*#;%!q{w=H3*;Ma{rO zW(UFIMH^^!X-Ktb$MV@Jkt!MGrZzIl%Sw6See$$tk*-QR*N+`5^>giPM&1U`2sX;Q zW0jU(KlW<8JM|WG)-NMjzas5v)Ni$Rt{(+EE6bpk#QwLMSpG)OIp(UPkfpWooON^3 zvtd)0NpLMxI?`m%SyIk|CFQb`%)PbR8+X)cXZo><>oN;@+W0baVM~{#W37H)J40Ra zDL)}!DA;O-FlK++a~K&5^*`3uTAh2>Y5D43bw&;bJwto8!6X#wPYFf1E*46JQlU&J z7b=9xI-9Vh&W_%h8Zo^oA>FY>D_1{4m@gHU32r^lw6jJn-Hh59^a-tYdb%$2lW}v5 zr{&bLTIvQ)s4C|+B8CFqW2t(^arO9<%!o;A>mj#xw}ER=@1{mHQl{EbsK!;bmUaRD zvrkK>AJe$;3cSU0`W@{|Sh>|QA2&hy&uD3pL-PH!7&G?>bcft=zsHb)cN1& znJ#XFNmy0Ro#Geq7Ad(i$Svn;IgKs#Lxv4tWGv&{_}gP@|GgcSW!!+tQ`0`SX2{>? zKIxYTfu-<5u-`2Of?>ZHinv4JXmC*UGj!lQaHzHUK=a|lZOxs{iX}1{RV@CI5yc@K z>gs6S3aJ`z>SmxSwo9i0zw>H!~&2b@<8wAb8g<9zH z?)x0)u_@+}LB)D98XZw=BVy#-dBqwD^#>H&aIin*_t+JO`nJCQkeE7`PWlxd4MdTW zk`oOL2hnCeDF{g1FDcm!^Z8NMkUdKS}PfSqCXrs`M9tXb#ILf z4@>MV0z)A*>DW@_NUcODvR+MDpN92j;2ZPBL^?hg85$ZLKHe5Q6C8?+45O&yhY=qM`-hHGBOdpije7BdBCst%(KDgo+2i

ep`%om{ACj7Iq9!J`C_yFSUg2WC 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 literal 0 HcmV?d00001 diff --git a/e2e/lab/__pycache__/test_lab.cpython-313.pyc b/e2e/lab/__pycache__/test_lab.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6f9f1a3651fda792a881b24ccefee2edc5e2c8a GIT binary patch literal 14200 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 literal 0 HcmV?d00001 diff --git a/e2e/lab/__pycache__/test_mac.cpython-313.pyc b/e2e/lab/__pycache__/test_mac.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2d51ee763ea24ebcb8123c7c165cdef88ab17b4 GIT binary patch literal 4559 zcmc&%-ES1v6~FVbyR*xhHHIX{p?Kmt*aP-DI3X^^h2W16T5uB&R!O~O81IgE2hGlG z@7(p5k_sxNn7)KiSyPq z%pN(FGvt$cTGlgqff>|olQV{%u}s^L^F^1*ImgP#Q#r$ySy|K7XI$BKSkAPw$$MyU z*ozh{olQ72@21x-TaKHobi?dCNf9_Df+qy0!#5EssshLm#z(_y2xLSJgOt<=jbPdrTZ|>oFr7H$;5rhH;zmoK!FotvfGg9fSX;(wHxluAw-n2CeWK67#M#7ceYFjx% zp2%x8D{x#@gyR}}1UH0Wm!Jy40jlAHA{@B?w+aC8W&E&?@Z6`GV=w8GMSlqE?+viH_NZ)(&9B&D*BWfk+OL1WUeoI>8PS?W!g zcWm8CG1Hz&X;ZAz&FR$WbPa2wbJ8@XQbxCtvh?v3GhC+S^>nf@<4Jv%o*&QXhrQz! zI3)e|y5^b|*wxZG)5>V3tGUc66pW0fGY#;nRj{1wvz)YUxrd<>m_nkuArR+D>6c?P z3cY(sPKYLg+u;=1J*2%7@kAVZaovTe*obbrhUB#m3GXbV=%d7=pK8;X8K=Ec0i%KP-G1j`i<|Q~~G_WzPXt z=1CW^xy=II=Kr^}RfR556-T*|IK;E=QA3ZV@&=V+vk{K+>!}P8Z%|KEX_VU}-H(^) z9vzRe%_$Fq3_}%a)lT_DbqXPHOm2=eYaiB zvC{@p+XlkvmgTM`J#!rI=z5AgwTT_*&2K@RC(HE>bD_;LW?`_j_jGCJ+oiEHrL)HE zv)1BSt28-neQLpf{1^TlQh&2Wg z-V_6{I_-jY3cTXfWq+H^H<-w z^3JCtH+Gb|&X!vBQhH)BH*=qmLH>3ApM*3X<1fYM!T{IXQsbi3cx}(M-8Y(-q=U6b z`~QdMzH(M`XWR-np__DB#x1yuJYrnwF$jo`3@z?8C1$uBzUDU#j9qx$4WapQ?VmajF^> zY7*6KZ;+K*+KoxwQhN9I%4ywhV{$sD+gU?)3e0ruUU}9sT2@mS9GTUo_(`rdpr_7R zuT^h9;=ppUCR8u1pPKDJqQnxGq5i$K79M->WH5c7Ctn0RyowG_L}z_mC}L1i#k7+# zJWiu8Rlb9oTE1<*=mX{ZT=0@l=W;79^s4XRa^mEih~={5O2?=C!r+b8Qghem+ZSIw zR(eZaY&dl(GRLi^j~&-0m!v%b;4$eBD=|;fG+WObn&!ncE$?KC7WU(shMBeeCZTB) zCUqI!9c)L_Xfu3Fai8dZ6g?=8fbgEt{Dg0&;pYIO=6De{0QCI|gBSjwwjlQ?3cu*! zt>yRR0WXGLeh?3b_C2WQL%k0qK6Kz;k`QVO+(m8lHLt@-YRWda{%aX04X*Nz>j{u) z{A-aX6>XE@u6trZXE`ry+V~s76VExO?L{&s#hB321pJNx*YFDE#f)hqU1a*WWdxTf z=@gh4(BV_x*Q2N;;@ay%fgei2o*kwt=pb0#X%P1Xj^qALhVGE)9TK}kw%j3!yF|Ds zU63v&E+j5=+^dQUz0cBo4XDvi;F(H3TU~s>ei1E4ETf)v|F@Evn?@qq=i~9l*oBYlCH>LauQ2+n{ literal 0 HcmV?d00001 diff --git a/e2e/lab/__pycache__/test_orchestration.cpython-313.pyc b/e2e/lab/__pycache__/test_orchestration.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c553afcf677bc00eaf219e1039ae23c93d9fa19a GIT binary patch literal 55580 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

swdM^y@GNHn4kqlnxlM60_PW?*$Jo~8rr z1;PT$ZwCBDTM$K}4}bijQD;B8dfH{H z63=60(aH)H5Zb7cF8z643F&R3)(z=^Ed{_rbW{+@ze#l9NO^JJm3@F}|K`2}xg-^zY-!L0?uzL8_W{Ovz8{oM9b+s_?8bx4ima18Ek z`wf(Jz&$)ANl_xkWQ(Ig$( zeMJ0OkH#If9kq*AHSTYRBK7&L6rtnfdfR7{o|~+VHcfI#M~C-9cJ3h&h$$5XCq7M{ zr^kdT(Sx^f5dl9A45IK&s$lN(v{O<6M4s|=@jNcFI35L)$w;bT72R z!x+cZo4>|`;zbmU*QUSt)hk~e$_gegf0&*3?f$Ed2Q>%(`sAIHcisQQaT!&n_uTK4 zjpV=6JmMKm9Y5unJk@*uRIhaI!p9u<6~4j*qH^<m=-Q(>*xmJlIt5VvC}1z8(9cK905(5g8jUaBDs@y|l; zHr8&j+0De}F5wNd1``iYqiIF~9TpL}q6iG)FnCIS3Jkj-XB*8>xbYEcilp=)DGs7q zGp>r?IyC9X4><=r0(mhKC=Eruuk8?KNTwv?ypFEL%K6 z`}u)5GGX*y8nBj>fS*vp#oitkXzE2p{Xn0UaiIZvg=^=by+6rlKrY29%=uy&WmWWc zbt2QEVx`@QYKmEi)HvC`t;^Hh((2hEFEIK(?Jhv1tZRCnlQt;cDA^2?%CxR5M#U*& zmf;$5A*aO5^0L{rw*rPy-Xrs8!$Ty6r33(q7z}&UMEe=mQ#sD(7vTjmewq5+$}5y_ zT!D6GXq_hJ=jlcJOtmKE4K@$bN_L+2$tkMLp?i(wWR1hS75hhoJy{=plEhhF72b%^ zsRMAEXVwp_3upLNh-Z{;sxyE-2%r&;2^XM3>0JNhx##YmdrpBG%@RU3-U~-R3{`A( ze!u7qpYVxmGExCUR5}%B)F~rkX)1sYt&1EQ+)M(;q)8x9=hgC}g6Z zS2p(xT?+pR*>a*kjpkU9I!2%N?AO2|oP&7E zo_~%%t%A+e-VuQm^yLf#OL0Qrpt)N)jIA^cEMf9y#CL0MWJ+Ws_O%klB?vw^AN}OF z2gv>b?Z}o|*f_y2R?--(A}Clo{cSxeyNLc)qG&M_1-^B>p=q+=a~gxH9J`c>#nj#-CxrO!|DXYWg4&;9E}54#Id9SZd5ePcoR`fH(zD2v z`H96ApZQ6eJ-&ngB*PqEWqO=oiqCm$=Tb6W9QdPwx6((C-fQ^z@t+=-Jl;TFYcSb& z+43+cdon5iep3E;Qo&IF14rtlV{yQ-_zlaO3AYj^oofQlHOP>8e#|cIJaw-eg>X6>gVfB5Au;SQ*y4B*42z% zkk%fO>b>K>=cFTFp&NT7XZgsbvE|Z+{Zm$x^B{jM@u~%BiBhvBQwjnp1#eWpx&PMw z$-?!4!u80-S{^Li^I^)~-`J??$966$&8W*iUh&R~(Qe>m9oWGX$K`tn_mWynF+P#i zZym3`7<675cMQa;wep>nqtBwDS|!t9{$AGVzOYs?Xj|?(x4gUdzi$1>*1y;ubnY8> z><=|(c$)&1?XTKjOSoM9!oE+lxp{>j=KyGz6F<$xIUu9{d?J!<;!gRVmHUd#KP^t! zx5*Zf6N8i;GyYF?pkNL-{Ea?nG0ai(QHzLJ3z61Zr9d#oQ@sT}m5of~ZiR8Q7H?`Q zFE=4CMw%+TTKpEj*{>~jQGc~*lQ)|L)L3#XZBocj=Djj6%6xzHs^>VGo!|hQr=hp< z`=8NS#zUaOEL-vBneUvLNUr$KnHw7i*9@hOX1{ar+i_P@za4k$Ofb1ZvR8aIo?Ic) zM_+T4*l*cN>{vvJNrF>Y8AaSN-+|&(I7TN7j6pRsIw2XH(Se-%rcn2V4aOP8Qg!L|C>me=c%P zCnQuLy*|k_PA@XSP&R(2$4UA4owRg?<;R76(%0famNKN_FHJ~5OAQ!>jk#T!*Gbx7ZqZ&;vEaXW2+crj zQq4BwnJ0f%_47SH-6J)e04Rc)CxecY&)2AT1DTb7?hR&E1|5~ZS2JbeDj-iyaok>L zD-g0AbyQmG6xqs)cJ%`>;+;Qb{YVf^?>B8aF&<=h|r3l0_yNi3VHP!vxD42V2pP%a4pe%{IT z?w;D4C)nb3{`Ah_$i5Oa2j{t!~v4lD4 zo(Gq2D=RaFBe)RGZe%Sr@=RToH+|lZOvJ0jKD?8RLg`nJz1}f&A-Jea%2*wAteJF_ z2OQ-i$AgZYmw7!>bTI$svKz~W^4~1FRW!UkxMcI_lE4xQ0bW8$&c}9)+w1kZuV)1o zZyHJcan=vBf{Ql=b2q)a>~8vBXWz;G3nUKN&y=nRoS@mC(Pabr^~LFu)=6r1(-~-! z-Wqjakw1Ds2ZF~{X(1Nffzk}@uZnOhnpM#j^v|%`1gu^QQ5H|oTqK%Fkc~{+hhRSg z>c(4)`l$!ixNO8HTy|E*hx)9h5Mu9vZ8sr;VoOR8O{8q%!V(S$efa7pnMBAi>S@Fb zVH2Cf2>rMhqGcF|jqsewnl0$bZ8gCcA#@ml64hh+QRg2et-D5gh{Gihg4U(zd^X`r zIpx~e82>q%OTnj!BsI@O24hM0E(9IN!bu^OrAsXd=B^%DGHze5Nx$!+7r6 z?{Bze8{*--^SqjWd&7MsPCYh)ShyW}%|X_Lv}AKIcgyHngxZJVu0NYHb9w8So%v2d za%Ewp(5FvfW9asmLn=Ue0uPQEh{bp!GavvUEcuV34rJ7gqbRTG*>v@ZMED9J8ujE! zB8yX1!r+9{xN_TOh;@v+{uAyiT=f!xlc-k1v#l)jQA3Q#5Y@2wRCfzoQ$;y@)Kol( z(320(j%rWWB3ZLUqKnzEO=|K59c|$Vr}5t9x0Vx*-QGaCc#n*lMk_}UDZOhtN7d2f zUA*thKogC#{7z8>27zfP0=+ndB3~yIIgL*eD6B)62Jme&0UUvm6!)q#8n$bX8lsGq z06p@Nr-t}!P395E56%kmprh`~f%bp=lAt}O`E$-J0r})P7h>Nu9AYvgT;n0Q{x1S4 z11^zoj5&r8IwScQa90DERf!JiwIfp&g1%eb-JVM^J+&^cNWR=x+`iUuD zjV0cLUUec8^2={5A6oO~hFhTU6~px-sl$5=(+AVoGl{7bZ<-5zQ#jIQlc64?M_)cQ zZ5!z^x&)tGzdCI80cugYHBrDaM4q2%m$bw|0Cgj3_j1(qUAwqLa1h$Eg zzZ97ZvXDc?yfh3QZ2xZ)?vZ7QNkJiT=eFr1TvXTXeHEuL(qsPs*x|JV21bIAF7QJY zFQmtrAoL71zZpN7A|4WiDjC1>xRFjtTRPz;pN^VkC5%amR82Zi?jE}obR3Dq;5lmv!#u@&NNe_v7wsF*-G9Gm-!01! z|5|>aXy5(Z{r8SbO&;lB%Y@zgSul6MA`fkxSD6|q50S{s2;n|X=0XS>IvJ8em`WcO zW?{hSU}S?255d#M89#ZWNF~GrnrK%;tq0+XK2omeNr_;RTdkU`SmtM)O%9|*OXy3* z5WXrIc&7|v9JY602#5 z>f|ABi%qn%KfRh@YN*PL^pCU$96Kf*6#+-ZSaHyC&ay@Mi)ynn;z*bS%C8~m_l%?2QmAn9~B`;3&1Ff>-%SlX~=0MX?% z@8Wnmu`x=F11ls08Nwk88qE;oA`N74SUN ziWI?g>+M~1DjeZrc~yW~0Bj7@V#^@@HBf7fo;;uQ(FhFzGifX=623#2^<9F21)uB0 zq4?C4U4p~XInbWjKn-97lJj`a(&Fe2WNcD4sF4poC1T9j8o9GX3NLt``*ozcIl6o_ zH%wTU>VX_xK}YwTfIk{PVXq89-jrOiAO_?=jDma^ThV=JVb|2<=?Ie7nU0}24kqK$ z*KYkT*~|>Mpw7vNkAa*IyBysYA%B(Y(YA2{bt=aXixmJ!P+IY|DWt#Xi`y zXu2Wh0`I1>O}4TR7Tcg)-ajX9GpDwy&~?#+ekpp|QEai=HsT8`+$Lpg56&w1ExWZ$ z$}JwQ7#4;%j@#Eo`9p@tr6R4Xmev|?0is*A{{!A1KGUp*-PpxrMo~o)+}4jMKRwCT zQ3tdvYB}n_RU^-v?xzRRV8LD)AC5MV;W2lFgb#wVz##rML0pwU8tH1Jdw9Aauk8e= zEREALq3LnowA7thvlSzd=I)+_Sae+E znp0SUJL`y4Q7`RsN!yI~z1D$9>m23|#A&Ma7X_qlsH7l^Na_a|k@7YKM%^=|m*146|>P65p?z-D+uuxd(! z>Qx5|*KEIv5e=SoHOfo%tV6TcTAe1{!K1X2fLD*+MQBdMJks%hDh~znWT1<*o2<(O zeF(`AD5R{MLh+G)kDi4PK%dO!{{eGZYnc+9!Yj%H-oPoMAzM762c*nMp$Zol;lc3s z(VopLscKk6in2HDbbP@(^Mfsq+|48+J|JJQsX5eDrV_E~cbUrsUsG$sbxbY#v$>C_NiY z=?dGH`?ha9xBUCQTdhN$!TiDM*O%Y+-Onwj9E}t9ZIDmPS#a+UQY&l;s^!2qUDO){ z^*5<_i;58{eniEOsrXAOi0wt&3vSX4DrlN#TNskPz=ZrVWEiMoCIOT<$F3&oe$up~ z2^k5tD>edpnuIU?z;AX;4dBn06AFibxFnYYf zNSuiwEP7|!T((4+%OX7H?Sc>659`5l^46H+KKsMR2`pPNkV@R?-Ya{*wg1K1E471# zL)M^US@=Yx1l+6)=9Uf%0fasvk>UE0OB42r>9de-jriv;03s%ASkM5Drv#HORzyXR z8P01)@uAvWr}{ZTbfE~cX$CUO44Nwl>#s1x!e3Jn5@GJ)CzeSN*+ioNQ#ZawV4-gh z**3IbM0JNh@~rD9pyel}9U+VviLR+C`vV$2eUe^E9MS+6hQ2b=4$ZScC1Co6`LZ}Q(Z899sP(!+^X%0HzaOmy8=nhjycBq1~J&E1H!3onsAC# z8VkC6TCjynS!a(}=IZGeyjUhu(c4=pUg&J=gYV$`XvYxzr*UIC_?fo(PxQ<*Hc+gJ zwA%KLSPF>XbY}E~pNQ?atmXNuoFfXryb-I77D9x5=!lL8(t<70{H>SwN{(%lj-3I= z&N0iF@7_tN*&B4Uh9gB-kQ4<^92qgi2%gXZ{X@Jb7NBS2;^4So~I6>E?o$r3~rWG(1CGK$R93z|7TZJ%qGCTMc2v z|H9BH!Bq39Hg$&3%7YH+3?d{o3_Uwii&ZI?`RO47 zBjxnjB8 zaCQB-JvU^8)MgNJPj3w_**IznETK&3OLj=eUcYFApI8W`#V*pDlvQ&y;<{v_ zECA^DcYAt!A(OB@P2dz$Ozg@ICs+l*@Qb2pb=D*FV>?W_ab`C2Ih!TbTfBr`V!P9f z(#zEkQZuhFxVB)Z{OW@HsYMSn<_}iBacsEZyCpcH_`fz%?1F_~q5n_Bc?YLSu% z@Rf?JicQu#n-VH*@ez`Yj_joWg)^wotQA_}AG$_naqMNNBYYztLU^*Dz&EBd6jvO4 za|SaS^Y5GRS{y8x_GwVwV3`pJ0U~zv;nHKsG3zD3QC7`k^9Mv=r<%XyU?R( zQxpR({5=&j^1)&|OG6MFcl9|@MPNC;+vD$S1HOv}Xsm4b<^5 zWs$+1(7Gi=5YUW?;B?tFGZKHUMoGyOyD_eqFc%aK9Sbff`BBH{h2VxgfsDP_=MX_B z``*|yTr*NLx_)Fwu&^=|bJBOOG3am^@#82&p37XS3tLOjp-5B>A!5kk8;T+D^NVO{ zw2{!QJ9L@IZ7@^fIU`gvTxgBD(Bh(x(6Z84Vpl#FiZ{1$o<*_A!DWezBBxZiE)Y+J zsqVD$w~cSpxHN=0hQKT^?li`1U}vWvS${fPkx`y4e0FLq(1{ES9`HYs29ycO>+2=&m24q_F3iy#O#=+^Wh>Gc^$3w6 z=+#V2)I3&#kMNyB8^TCI(JOQ%qMH&dxe*ZQR?;V7!)y8E%#`p2o4-sn@ePG0fd7rJ z?`3o$Wt0XTWtaJnP3CwH|G<&-V)d2ktGO>6LPDYVq)9t%E~&fCLnN?0xS~SJtsFaY z&m`5Jk`B71>eCZ;&u<@Fxs==~j%RJLoSIVBG3gn1Aj>`JI2~}D{{KEU)6FL=`^jKx z#WL>BvV_Wc<~yr1D&x)X#anS6!R~b$S_H-$lZN!Lt#BHe*+OC@uY@IlH-%CTg!?i! zn@MhB)M>=Jbt%;eET?~(gv6*dGn&#kqVg=mtK=_@I-m#xh;(QRs8t0yA@r8e7u1tm zIO>302)D2w-r;)Vz8JkVvC&MvWTSVx9HBSYmW3p;P?Cl)?m)iksDsv#gs(9P;|@d7 z+#$A{SNCUX&gLXFApJOA^CY7WrhBB;0FMBN=oOv&U5Dy!^Kv4y<@(y%K%|N@d?jNs zED49xr?CSkMYbu7#Hp?)2{Dv@z(HALP6mg8l<0*nEK~{s;UQ-859pGxj~?4kg%dyJ zgrk(uOi2e#%t-i0Dn6znD%{3{YY{87enXW`pphuo$1cW+Lf_-ozeijDB8HYrkVvU< z735j#!{#@le0*ju^aYwG=~?_W`mCt2ky#vI1WQVN@tG^nOeQS~BrSSf9ICsUARX`o zceO}Ki|!|R!Jv|kK(b7|Zn>NNRIPb`HvH(v#A*2`bhaeiNkEK+b-{&wiaj8 z=%&E3s^G%vvHAc^Y^i~T2kssJ&~XfMX|D6Pk8NDWLa;T~10=P+7BA)PxwkZscW5%@ za3JL{aW&j~@~MsbG?C{d;>3l~*wZj&{_~xdFhscuR$&3VsFe}|tTWSo%3z(n*M>?RUk;ykYq725}8D&r5 zSA@IMtovyUb75Zz?J6j*oEaA*D!)e96{%=9yoUJDm6MLrfTMJ{Zv=wfRwKdgDHLrT zCVz(S51));S$M_bPph;vxW-IH~pbn=9h&zoa_)iSTI1;8Yoau(vPg!%OhcEb6 z%-#g&Udl_Q?*A;$>P(-#4T^OW4`5hyU)kV!a-=VtbQA|1#lwXo2(;PoIRLDN*<}g4 z(6~@RMI{wgR1irBKc#W|85KXL;yx80Qt=Ba{)USGPWApTI{ODI9#Qcb75_}dzfb|) z0IA@psHVz0sUYcI$zyqks!&0)p4f)#6qrXldDHfdl`JH0Cq?981)s8{&usM|M9*S9 z!WQ|RMh%m-0j0&-j4NgJM{y<*)c_u zN_0$LXbVV0-$f<26XM(L*d{LhuupKQv|Do?F&2KWuahDb2bvl#VB-|^mPnhXz)0oP zoU6znDE2vh9_*`f*5~V0@&_^jot$OP_8w)2IUrc4;KcG?sP(F?D00VeGF*@~Z|Y+V z_$kXNE9PVNK~xyW@UBry=tvR#>j#b-lEaV66wos-_zbQ-& zGcd*&S^YvPlgo|vXE$sR>qx789ob|w_5kwNzq%2Fu3eA))voy2zDZNM z4Emp@^`YK?fa)pBaMS??V*)ggc4jlu*~doEx<66SdWIT1Rm%$;60|;sEgl-M6Jj!h zEP<&3E`+1_i!FU{S-3#e2xkUtg69I;Vkn+wj~;s9Ba)V2=pfTtXlo((+Aswmg)g=b z`YyF(y&%vEfPbM{HE2q4X8bAr9HQbD3fV?WSYcgdwie+as$ui3{ywZJ^5G4%ELr#- z)w8m-m%Z3WZGvSGUkdaAy z1-)K6~YEU@XAiq@g0At5ZtRtnwfxsP zc{go0Y&RV@97C=*Puw~&QXI_LhOLLt^wOd9@yw;escO@M2ZjsYUUhrbNMB&Zw!ngI z;~CqjiDkde&bvNvZD2CHIFMaDk};NfuMOctQg*SFeOgL6{b?dzGm*LM$)|CsJdwFn zvCsa=_NsK)WS3MGn#p{TZ+pKmp=zy75vP#kZWlf=N}R%mPOv0(db@qtV7XPG@ngae zysep-r$vkmr;M#^Q@M!XzzyOg%qINXZ*UKiavz)Gl05vBnVXk4#ZDDDDi<{)wnieQ zjPaX?I0;wC8+F47sLmQjk73g|?!-058F8UTtC7mCvCG)B7|qIQkDM8(CucVLqUV)5 zLLLSPltlP1q+%Fo<05Q;ZNuKNo(pUP1v!rP!hw6DkLskLj*y6lWOFOLb~I2<KpkB*qjqF-JmxL_=(Z5eLXN>VVQSL%64OfHp(Ilm8_T2xRlI^ zthGIR-lH!k_5_-~bBv**Y*($JG4|3SCGQn1^$hQlu!7n_e*g`I#ZX^_0$h2Y?vPyi zJonQj3cfEUApSp8fv&UINVZDqi4EEHOOeE(IEiflB2-hINCwEZ@`y4yGd8H~u~AG< zJcCx%U`jZVv404Ap^0wMm?UjWhpFk;v#(`S zOu?XcXnQbq&E>dHEp|AC9&=Pa!d4vFj}y3gX_4mO@$!QcNwp8Lr(nXh1T4S`q~yO* z@aBqJD~7Rx?BGO-;jPZm?1_|$U!42e6t=^vFx@}*HR((@w$D27(t#n{aL$j`y=xwA z9jh8Waj)RsC2Z0$?r!}s!xuRBwcoJ%A1m9h;7IzEt8 z``M#7YF?><7e3KzO{Ua-m{R*hsX3Wc`(aY;6Smdzoi%G}mYd&OvbrY8`hJ?VdadpK z>r3EjQBHlc<~yt~bY>mOL?`Ugn~HS^;?$hOh>@`Rf8 zk@jQVUPZ~^Vi__tmevnw)BoNy<{Z)_NI+gYNdF=9CxM3kYC;Wyi0CIfv^pAt1cMD* zQl&qM{?I{;8DbChGwN`e8ZAaTnAY3SyJI|W1_L)Rrc8f6nqf!(o=Fz3%btyW>(V-w zU=mYSM0OH%pb&?CK(xkM>mm%lJdXlTg}%C;zM6CWo-Tp0`xSUpn2*~Usao4Q1?&YH zr-(($mUa3XQMO)$=v51UUdC*+q;Q8UcBFYDxd;5ult7Cq5{Pn}uFxxsVP<`n*6fIv z(M?!x7UthMm)-OlP&P4GvNUWo%85Tr*^?*Yc#(|^4O2Rs;5^Z0CbD@-q&8Wy0B}Z>lvtm|M z(~UXuj?aZ|`t$#jQ0^o;G8@XR3@j)ei5qz~u)1p8UacTqVjvCM1d-URB3dcJWS8Au z_Jg8v$2#KG%O;bSewYL?m^@(b=2t8;BTS*9JQ7`W4olA6r$Uz~UJAZxQh6);TW*1! z#G>0t;FJd+#lR~^J;?%5#}aHlq;W;qKCqG^k#mB-`l0O`ao7_&cRZo{_!{-#1&x1) z>{|M&bd%qL1sp0rV;J)hbqAb@_?Mz<-NpsQgYBWSA1n8XB83nREvM?=qia7vF^y>{ zJ_daUPd~PFRMI&1`#aC|BXtN?n`_Q%d1q`?QVo-Ar^lELj1w;Pq8q@a#RWH?yYbv> zUk%t7F!q)HVC}|H+dHLW%kE|0DU)1H((%@S%O|yWOa4oN_JP2fXM-uv-Cy(UaK+2% z*B8CCXvq9w>T+DYY?V@;(}VS2Pk-Gtl=<2-uPq+VpRlj`41VR*ukeh1zVED9V^K}i z2}U}VvQrWp-!dAtwNz}NqMF7p%FG;3H>e<6tVls1v|UomBTJTbx9QPpt99L@c@}H= zC$JxvC{iX>_M)DC;6ZjwEyJHk^N|aNqiEx>U~7+qB9d6wquGPSP8n@Pi0Y)$Gv1np z@)eE@s4hMa*$OnYg;7>{E6SP8w-6jmGuw%bCjXF~M+x^-B6+@0J8>Xf>lbgwC|=KH zJ3%AH4p^2{h`8dl_@mI*7}=sQwy^G;&@Dq@XPJ7d4y{!PW=Z&u1^Alz6sx(IDN}>Z zbgR>B_rZ3+grbjQW>*Rm9@Xz*QBmYyjykX}d}?Gp62wBrUp1Za5^x;Zwv=~Gc zSt=}bU5F~e-%!lq4BGj?Y~o$r*JrKq!mKr3QEC*Y)kTmXNRk~>#5N;Iu-QUHsL8Tn zw%dJS1gHpZ-JUMweD6l=ZL5I&SOrDWW9e{}#7npXZEm_@mm)YK$d^PTW@y>P`ZF`B z8W~T>WlDs%nRZgM)-?<`T7;gnKEGnW7LxJ7FmEu!pKiav1t(soXszi~gJ*_2W<^rf zXToQ>_DlP6GT)KAPoxMeSnne3W}~O1#-q$?c1%i9i~tJb7P8U1Xim&j=xw+`qp5CO z2iw+fOng$4X4|6EkZns?f|^1hieg@NC>y4_VPwFzm-%Ri_E3c-go*3ICsg&HsIbr& zEui9;R4hZy2-u;H0z0aRO^w4XB)n`v)?Huth%)2I{x3eFn&sqwI|J0Sp#&$Iv1Ly)RBy>>aPthmzQ3XyEuQjY<>UWmb-O`l-j( z$%%@NwcFDr`s4)VM}yGs)8t$Rwqtl&jzdIoe^;MC(RR_Iu9EOd|BRUlOy2Z)hx3>8 zYRa1bJohO=bes6!a8#0gBx^FM=zdbsc+!etZXn{P0@G0I<|-1I2d(< zSyH-wmLR!0gL}`gDrYI?&c#2>U2t>$tMiAB4R^e2e%E!k=-$R)rAumTlAiHOzK+0| zXM?%VU5$e-mfFRW38a>l$ElpR^5c|HfL_*+J&;>GZeIbh=*8qK$%Ao&1A&|s6ZVy% z2s;<89#JCf_T8%qx%E!b#+oeKdyDxRYy5lptE=v<^5bc?!KRIN6ou=2{op~ zyM-Cm+Y|3@vZChQ?N(g*z+}ex2iAm|^rR1xZFuT~tc04v#1EXXyjYp#CH{joHni}; zri9&bkvakyCYjhn#<|%&)X3KWkw_6xO3kaWt71q%Sx-C|2j$mL?KB3qlcscv|BB4P zfN4^f_mwuNblKsZ1+SokEuljY31cNkaDkO0>WtS_cySA;&(*#Ys1gQ$dDA zMdWA3iVpnLJShsFmX%D;o>25@J0>Lm^aYjjx@n{``$H6wp~VNyUo<&?<^B09hxd%s zj}_b#rPHl}&5+kSrL(=`!iC`ciwJ4IY`t2o%jSbi2Nw?Kj#LgOkJ~p9Y9?Jty4pSD zny?o$ZWX~yb%4HrZw&W1gstenRHqFroAR*m2p}MVCh7>SqA>DkF5yB_9(8H%^1?_98o4x(ueA>!f6-&MtP@%Js1jMKNW|lsHQ4W z`qO5*K?SKWB8kuxrju-4^=OINy5bYW=hUk+HmhWJW0?oEQMXWq`VdgAvOf*Q%N4ba z8RZY)nrw&a+D8TwVF-=Naag$mQ=e>ukCN0|87;LTM+#bU;ywchgOhA;z(Z9Y)TTHG zVK)_jMa4xlD}0U4h}{X7sCbr&m#Mfz#otn~o9Z2+;$P_J4Jz2=$)?ADq@Qe#?4>FK z6%<*?VwIRC$%aE2PueObYQ$vww(g!*tVrA;9K*1o0w=zT5;4&{{|oNOFS+<%atXiW zl7GdSziIzH`!|z+FZn8eb?xwn;~xk(&FY z!~KE8^UvEK$MM)4`>{QnKh0m>JLy;$a4dYx(XYqli}+Pn?TSC(F^3-?SMr=K;hXKh z*Z#cu7q+C!-mA;5oDJIYp0`jd0|=ku`IXdE4Ig@remyRC^6g>Q=-1=jd?sJZU+tL8 zS{}$+{+Od*k5}9HgJJ!kUsE|8pT@p45nuW@T<)*p<~?uzG;SMTi7A`P$6v*8?BO5V z&3v8dv7-n!putU(^H&AtuX@bUug6FEh5YuRrpcun0!ueM=J4b3F1~^1kMM&RCl{{{ zEMEPXV?Q7JO)L45!J^5$m4UpKk2(B!+|1`<=iaMDlW7Hkw1USR{rY$lXK`E}2%2*r WSRCK1{r%cMJoK@dv*a;4`Tqf9Ri?K9 literal 0 HcmV?d00001 diff --git a/e2e/lab/platforms/__pycache__/_mac.cpython-313.pyc b/e2e/lab/platforms/__pycache__/_mac.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae02d9694e8e35d0c4bbd989cab00a5e4e87d673 GIT binary patch literal 10430 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 Date: Tue, 10 Nov 2026 20:32:53 -0500 Subject: [PATCH 2/3] Drop Python bytecode that a lab test run left behind Co-Authored-By: Claude Sonnet 5.5 --- .../scripts/__pycache__/pr-gate.cpython-313.pyc | Bin 15001 -> 0 bytes e2e/lab/__pycache__/common.cpython-313.pyc | Bin 15747 -> 0 bytes e2e/lab/__pycache__/coordinated.cpython-313.pyc | Bin 20963 -> 0 bytes e2e/lab/__pycache__/lab.cpython-313.pyc | Bin 36456 -> 0 bytes .../test_coordinated.cpython-313.pyc | Bin 31656 -> 0 bytes e2e/lab/__pycache__/test_lab.cpython-313.pyc | Bin 14200 -> 0 bytes e2e/lab/__pycache__/test_mac.cpython-313.pyc | Bin 4559 -> 0 bytes .../test_orchestration.cpython-313.pyc | Bin 55580 -> 0 bytes .../platforms/__pycache__/_mac.cpython-313.pyc | Bin 10430 -> 0 bytes 9 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .github/scripts/__pycache__/pr-gate.cpython-313.pyc delete mode 100644 e2e/lab/__pycache__/common.cpython-313.pyc delete mode 100644 e2e/lab/__pycache__/coordinated.cpython-313.pyc delete mode 100644 e2e/lab/__pycache__/lab.cpython-313.pyc delete mode 100644 e2e/lab/__pycache__/test_coordinated.cpython-313.pyc delete mode 100644 e2e/lab/__pycache__/test_lab.cpython-313.pyc delete mode 100644 e2e/lab/__pycache__/test_mac.cpython-313.pyc delete mode 100644 e2e/lab/__pycache__/test_orchestration.cpython-313.pyc delete mode 100644 e2e/lab/platforms/__pycache__/_mac.cpython-313.pyc diff --git a/.github/scripts/__pycache__/pr-gate.cpython-313.pyc b/.github/scripts/__pycache__/pr-gate.cpython-313.pyc deleted file mode 100644 index a49adf24ecf1bf37daf29f163c71eb9e903ef1ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15001 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 C2!`eW diff --git a/e2e/lab/__pycache__/common.cpython-313.pyc b/e2e/lab/__pycache__/common.cpython-313.pyc deleted file mode 100644 index 69471c7d7df6f36556f5b6d6be0d0466e4b24066..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15747 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 diff --git a/e2e/lab/__pycache__/lab.cpython-313.pyc b/e2e/lab/__pycache__/lab.cpython-313.pyc deleted file mode 100644 index 7a44c2c3791e8e052dfb08a67da1aa48211d6e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36456 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 diff --git a/e2e/lab/__pycache__/test_coordinated.cpython-313.pyc b/e2e/lab/__pycache__/test_coordinated.cpython-313.pyc deleted file mode 100644 index bf3fa5207d0a06916c405e45744063f02b9c20eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31656 zcmeHw3vd)inr8J&U21jf{g!}60;2}CB;FuEMh{*F1gIpCEKIxAYKaD^Tdr#H(Cv6U zv$s29XZH+_^#Z%TKyxv%7BjvubK{F)BYZJna~}3$H>L|UZf%*}bL?*HtS>I^Z19|C zxr@8|{;aO9mMA@p?TgrmOTk}NSy`D`S(*R;{eS+M{mA8Va0tCWe{`yJC&&FAU1-6c zJbCmtCXRcZ6F89*OoDm8Ni?yeS+uaDRkX6BO|;=?*`M*8U9`K^w7kf(dzoS;J32%M zJ7$Sl?C2DoI9m5RpL2;WH+MX z0xx6=4k1f$)|&-ay{VoPvX7XAoVpCLyp*frgxqpY$UE-r*z{y+8!c*_Sjkf6BW1w? zDVH2yDik($bDTe)QoNEe8EV?xA4+U{I9m2SP(Zsn#8ixCcV#qN8HajVJnp(&=bq#O)6Rf|6AC31#2z zF)7x={^&_M4o3o~m8^hPNU+~yR%-l<3`$MkB7?Fs@D;;YR)6qJC=m2Y=fi==IcYWa zhDHLr75mvxxIc1MQfxz^@aVb64zD+OE*cE?-3Jwjh zT*n;Ivk~t|FfuX}94kpH&YLPNB90ZN-$)gap_oJcN@nm}FfbYoMZ$_*3=ReTQc%ep z8S+O5BI2;5xWwQ~qaiWa@AHd;sA)JD?3V)R{UA9YxJR!c_I2(!he6GWX2FC(Z7%09 zq%EK}!3vro*g)+<1}HDsK{Ev&)FEVoW(f{Zr;r8e5}csff(tZ9$Og?7azOK_i(|0m zfffkp#A2aP09qszf))!!pd~^vXsJ*lmJODA%9Mh%4%wRQkDm}H2xxVu_sPb88X}MW zHiP3%;7vNYj`aJK2B9}O@M)mxOrY1Q-sQLsJUu(;gQSxiN~J{pS+i4eR4V^uY=`s7 zIE{I@x!xS@?i^3&YWMY{_B3jgsm1mdYG)nA+L?arDAUiiv)*#;%!q{w=H3*;Ma{rO zW(UFIMH^^!X-Ktb$MV@Jkt!MGrZzIl%Sw6See$$tk*-QR*N+`5^>giPM&1U`2sX;Q zW0jU(KlW<8JM|WG)-NMjzas5v)Ni$Rt{(+EE6bpk#QwLMSpG)OIp(UPkfpWooON^3 zvtd)0NpLMxI?`m%SyIk|CFQb`%)PbR8+X)cXZo><>oN;@+W0baVM~{#W37H)J40Ra zDL)}!DA;O-FlK++a~K&5^*`3uTAh2>Y5D43bw&;bJwto8!6X#wPYFf1E*46JQlU&J z7b=9xI-9Vh&W_%h8Zo^oA>FY>D_1{4m@gHU32r^lw6jJn-Hh59^a-tYdb%$2lW}v5 zr{&bLTIvQ)s4C|+B8CFqW2t(^arO9<%!o;A>mj#xw}ER=@1{mHQl{EbsK!;bmUaRD zvrkK>AJe$;3cSU0`W@{|Sh>|QA2&hy&uD3pL-PH!7&G?>bcft=zsHb)cN1& znJ#XFNmy0Ro#Geq7Ad(i$Svn;IgKs#Lxv4tWGv&{_}gP@|GgcSW!!+tQ`0`SX2{>? zKIxYTfu-<5u-`2Of?>ZHinv4JXmC*UGj!lQaHzHUK=a|lZOxs{iX}1{RV@CI5yc@K z>gs6S3aJ`z>SmxSwo9i0zw>H!~&2b@<8wAb8g<9zH z?)x0)u_@+}LB)D98XZw=BVy#-dBqwD^#>H&aIin*_t+JO`nJCQkeE7`PWlxd4MdTW zk`oOL2hnCeDF{g1FDcm!^Z8NMkUdKS}PfSqCXrs`M9tXb#ILf z4@>MV0z)A*>DW@_NUcODvR+MDpN92j;2ZPBL^?hg85$ZLKHe5Q6C8?+45O&yhY=qM`-hHGBOdpije7BdBCst%(KDgo+2i

ep`%om{ACj7Iq9!J`C_yFSUg2WC zz$2UhSb`{aUnqPgayp3GXGx*{pf5Nu5DY{W-WLFZ4UdilD6JMOI4QyZN5nRpOh9&~ z4((prv4hgh3SBAww}KN1BtX~TlVwOs2EHEPI^s-z#Y!z9QT5!fh+AP2URvH0{Rg6TUB7J%EE`Ky| zQnB`j&|v0>q}YSuGa(W9-y%gt#U^1OMMc7T=-;PVk3K7gqCsC2nuB7YVeZt1IqUFt zJiuyaji5Ea6#Dy>3}IKt(On%%20HsdXpoM>!&F4aXjtKe)?Mw*9s3R`mO%8Jl11M# zz?h6Awoth_(&+FoUeXsh=?@PEB_(&*9}W$$ewB=Ih(Rcf;XtH6sANR?PSMx5tEvnl z)ZPJJ07cS2G~}_0yC`2ic#eivupfhzaUdTt4GV}wP4lAL?PgyNjX)hzDVwvex{+L( zz{kcHo#vehzEb8Z-{_64J{IS@9~4w13hM3^)J+vMj9Y)7M}k*#F63OXUgNLwiP9Rm zv?k7b9u$^dDZEyCwe;GOt4pQ|S0QEQ1Eh3Za8T+u%-0-O9TO+s5pEX#yzI})Zgt69 zpPSmaKepn)6n`+m3oew^Q+75%bY;2r0uGxIJUlrxtn_!^n7xltIS<0iz$3LE6ih6KM|=C{Xo zp!m+|qO!|9mwF~DvNtfEWh0NTH}?_WNB>uzQ0%> zKP)_0`pjFF$+kr84!L&6R87+z%dO|$&v~$P`NWDhJwNco>e}V1_Nk?ZVn+nIEAYr> zE(}s;{HGb*8t-IZjK?=bqhDF^hIe|?mYY>EemzB0Ug?i7T|Zr3fwVafipwvbx^ya0 zyh<)!^;Xu6p1W1w%jb(~-GprqpR z*rl;VNsU}m^H#-;Q}OnZSV>K+mNA3Sc3NY(6#!pM2h1t_`-wB zEPuJoaj?!FAeN#9LOaAI9{m?|<=43`Zn1o^JHN}i!IFk^Qn_~Lb!g^3trQ%gE0c_& zGqV?zl4~(xTbHdPrGru$H3$~`SqarQaA8;u3b?%jbQF8{F{VNAUA)m#x+d4f3ryoO z!gPXNE8Wc@9ZxxSxU`b>qmY@F&Mr8p?p<~vi;jY`muvoj>`hp z63jwQZ%Xs-O=+xxr7J_ot;+~!c4c;?birgsIN&Q7Xy1B0((+8@F68O?L-T+(Bow0j zqB;xHLM%cl&PWqc&nlpqa1>W>fo75sc62%Bs0m4}SwXK!7j&ArT5f*J0Q5VDmXCJC zm#_&-pE|$PmrBcz>qu!S`b(_fJj>c2+q_5*$fBgn(Tlr>~nC`Vwh; zjO9VnGK1!zSM;B)8y?vpk%a;0DYIqYd4QhBSyD7OBGsJ&P8xb#^)ITTRgG(Ft0=On zv5M?>!Tze+s>tc8#;7*{Ah>t#1_;eeB_<(_k|5ubVA2Id zOY#zsY~999isj6JDAI`XWB`ZsuF}1KZyKWI_94WkJLj=Y+t(aO_ zTPmh*PlotgbYI61RGCVOvI77!R06ax3WWivhQT4&CZ)&DBqm_ZJC*~W=@o<0=unhJ zcydKQRkD=`!#y^j;@~;4lQPay0Sx;}B1R`*b=$r@yM#{hD5dXZF{2~>{%BAPP)r}i zSm{G5w*JxK5lQSvj3-Nl5q1JI{&2ry0di6-LyO1)HX_H;-GU`K(tnFJxX>FT?&K`~3scE=cWFvTIesxj}Yrh;7^#cRq(m2zb}>gwrcKy|FqW?(CfQ ztd4n`Wl!_n=GfsA@_`f6t5&~z^zN?DET&4qG`{cq2R_T<@}K!Mn_K3N)jj(c(u1m+ z8_~NS+%N1hjq@M#xhgVBlzQb-Z=A1tuzbZkf!OY&@$M6`UB1|mI9=npapcxodC9J6 zPwh?5-3@ZpVLDrNw-C};kNebSuIey-X0sNcVEd;IE;E-v(8Xw?WQ|<1CeGJRXFA7U zmNSL0DXacpY!jyT_hd$An1j*>dxe*Q<#-{hyf&2heEI;Y^(Z(sO! zj9lMHV(i~Y}HVN4EPw~ci3Ko*>1u1K7stl`cl^cXk z-7bzG-Hf)R2iN2Oqcb2)rfSa3FbU*-9oZ&((ZXuzGU;|7E!Q0;&Ei3mRgfj7PP0)< z3k-WS?&Y{M-0LYQY zWAv8w7g@Kn?jDeL_Q;!i;*~u}_D@XT`Rz?xO^mIN?Mc?feKs;W)Q?FzDKc~>==Q@f zgtviAgayE@*2yh}`XI{&-H`z|D(qHY#;s~r9*3&2+67GAfo-!kQ!L_WSbPyxRkBou zzU!q?{}32wFs$l(Nj~2RsR;Ekd>&t67bS;$W7#mR`o*Mfw)rXBP}%=AevlqiPZ|b+ z{`Vk%Ng{vcz5JCE{coQB!Re{|b>sGFKIhe}3t1Q2F7LgxH_k6%IwJAwHwvzFUVGu{ z3sYrlCXdAVdJW}UKBq4@?eV_7&0KX9P0knJy=7Xo^VLoBAG0Wzm;wP-mtrfH zttmAGlLTBxic#rLbeTI+W>`HojbT7X0>iKvrP9j5eXfIyNV7sO8A@2d{gi26i%Y9# z8v9#BPK1YM1+6B+%$!n2cRjga!yCKxYwb*9mF!)No-?5h7JAO04NzK@R)&5QGW7Dm z@a^p?nyw_1C9{1R7%VaHzlR(YI}(v?iOC2RijN}Rlh4?T_@_8$tVMj2&RzsjvVh+F zfgxfr0LEev@Ka;l2Px5yh!Ci@g>!1&e)0diB_W>>XP6vY{VC=Al184f+8PFeuY*D)AWJ_Nq zTY5F=*C2E7r~IHN+ zkHxx=C%XM|xBpX)3z}NZpK)9d4v#p<*fzRavWqVAcALj-nyJfvE&FPAqIC1*#<#a$ z-ws?lg8?R%c;zMDsj|8orZ~TD#;w`B(RIOfF*H$HIFxJ#{e`ycSbm_Gu`fC2bMFFcg886=2wB| zQZ@>`oS_sO?@d`HIt;7=4B5`Z0K?WUYX@oBvjR#r(9tz!2iuV0Q@w628za`k>SBJBO5~o<5TJn)QlTW`DNQV?O4hr!9 z5&6zEnK9SG8+p-mo4TtvCZ7vidkMm@(9Ly_7BDN!Z#|rU>;P!kR4)^wQAhxqg4U9- zGg^BA2h`ADf~C&33Kv3#U}sl6U8QnN`Q0QRz#*+R2H*v?$>x4WrgL+(Jn?%iYgdi#n~7$*{F7%ItU!`Jl!USqwMVeia{yXq?&JrfoX=;2H>fF zabgs3?u27!g9$aYv@BFpR|0v`+6QtDj zFs}q-3PlWxL6WvU_!~lt@@d8vU1dsIPxJ_FdXc2OL}s#AxLcmPg4}$B$qgtm15{_~ zl;TAqe+U96y@((4wy?ta``KKW_!`~oBJw&V$W^UO`oQpHiho3RFB7>!XTF<0vHIdBqtK7I!f^WNh`gCqNG0ofnq}wJlijApRi8`rV6%=w>`)& zzIgW9x2}F`^4Qd}jWd9=mYExo)v%I`{YI*BaaohNw z>6$I?J`-EjJih1RA=$ZNdhM2*HL-@)@jbD^T3C{%UAY&VQg)@c`rkhFqf<9ars|sG z&X#FsVZymmcCMTV$QzEtogJvs_WYzg{R|?QX-861HJ(ZdRrVs zapJQ?h*=rIQSm2qgwGYk&pW=JCEs-wv zBI_USohl05sj9?DuZ^b|EK27$(Yc1Gwl>Ite*y^2Dfq*^-+wugvqH{Uk;qvi=d6j< z9g}m8jawh&l)n1%1>D*w=WL8^YL6Z6oXY7!d_m>qrb|tUf^~Aix*Hp&3btUD5%3Rs zb<*m|V;c2;nEA}oPxHCz)#FyW73Y^3D&&g=ymICKsoVpLL9$nh5@oe=S?%P>IKP=H zMsvLOYgt!OhZQMMd!^`F+10Z9eD#x7S-W`yH3tJAMHl|BjJWN58B1Tq2JTZ^r z4vE5bq|lw38&SbTy?PWi8_8!XwE_CXET4hw6H?d;5*K+;KKg8xhIU!Gi_g=lyN+*32tu{t@9DTwFIWwI@E$~wJX71uFWs}X#-F+{0mSWJEm zhy+x}GQG(q0@9e1)=v2PYMFUu%#O$5%`c6?o=g5QwZoz4aBb8-46nIbF*qs(Yhkq| z-~KVIJP1c+__7|D=VnLJg=7(;DzZo8uY?UGnS)8!6Aww z#Ffd)G6y*?Nngdbv0?4HhA}7Ef0!d4{KYVBNBz-Ig8JzOv(+#Rc9bs3zA63`L=&Fy zliC+nMJ#brB|9WRVZrJJf`V|5I*3TkkfURe`>*bw;%ij@ z9M$V34j&u$iiEpCb~oI}lillOe#yA~;-D^nO5R-ZgC&zMPc3h{l_xK6k;_`|zzJvH zya|rR`2!@;$kH-2v4rRrDBUiXZok?2^PWHJxmzUf zXrC%Q6z31?8I?>_#rc)=AZi*b_Do_5luShFRgKl}oLb&|3su=Am+g-2JrU=9vy#kc zom+6>I!Ia0Q1$-S_#PC#5>cXeQOe;O}$!)Tnl&4oWvG=rR=E!zp=hysBh= z`EI1|;)#@Ys~4YnLoN7f23g`j(9(VQYv z$uyVnq`NhEdeYZg65V)0$=$UM?%qisPV)O6%L6YbV^O{8=1C>jtJ%6?hCeN_nL@C_ zFijjH-6{z(Dd|*`%p0QM7}cqZ$oxWq)tyX#c}rM?8bjRQlY5UxqNfEF1FsVbvS^+K1JP@u;4 zX*P>_bgHkAE14oBjtK_cG4q6+xhBDHmif&$bK?Bog(XJ$(nR@cxqS8HTDjbNAqN7( z{~)gjMs@$CQ&V}%$1|pjD=&vHg(r@{OL1ItMZ8iGTh$8rktjVNmmZiZg{JncIRCQF zOxMI}+T`-KMA;#^?9f!%k(dyQ^QZLt&s_6f^-k8w;~h7I zdujkPqHZ=T=;k{x;v_&fb6~|OMaoEJVzZg^FjgaFNmq=F%L?oe7A}y^N%NLvj&GM!Wd?XhAqjz!h8dBxC$VvGxIa!ad)H(HCOv=Q zKb3G*%dYAlK6k@;-?ig`vn1hMcF(zN!un>`53;75wFzf~>}+_aBC)pZ-rBZXoxkY5 z-5u-dmDe7RJ6|9V=%$Y~Xfwl&;67jfg$;L+sp{|hX0xlM%JN>7qou(OYX%N77)E%?VCGAI3KBTC{c$dJHm_g8Vs6;+$hDGG zH}N|}euoIzTy{e%A&pnHUykEU$<@-6HJkDfFHiz9<#&p|OQ*jF0{==HapE5k`By~# zj>zAGcwG7@Tg))}OM39TM3{~83}un@yva~!eVF5oHrKt54XRWn*^m;kJWTb`q0tqN zM16iAIfz2e`ylU?-E)qsFO|=msG9Uc5Dcv~J7S$(F@IkyG9vGLX?oMvTjyilFT|vC za{YO_IvYFsyjR8XB6AEs&S?16 zFXp-8+3iLPQ1$ZWm0Ej}Qp?&d(oD5dv)K8uF_&rzaKn-MbWrp-+4?9ItNsIW5`RU6 z;Dn(mW0G$8iIBV!{}CizTJ2y1OI_;({HU%>QcI#yrCM)bZRiVPPX$Yv)|T>_*|wN`F!scQ%svYBr_h*OkIV znMW@3Ov0z5P9Ic-G^i%c_xUwn*eN}7e$1Su|9xXigXO&jM@!R8ftDIs)TTz55B-lY z;jEwwD`Dn%q5N1dGMqD!V_-1XdcV;E5|nSCP-{;-iQneyzk{6Ke+g%Zk3bX$rVr0x zy)Jx-uJfw<`XajI>^@klGWVoYk`EmXSSbPrPdK5%+dULb?}^IJIlG+Z*0ewlH&Jux z00?^6a_{81n44jxCF%WYK9Dq{Uo|CMJ3a*Vc|@XeqOrN!a=Y5my!QY16q5&>?)%h9 zYJ!Ul;ulDce$Rhuq&|21WRQTwF^E<5sg26pZpz-{O#&~o3^ zx+nqIW=gnPKXkRKGVMo=&0foGucLX}Oisn4D$I_tJ*lLncOocjv}YPR8@d`PZ0Kw_ zQ+EZ!8TJKpGBpj)ssY`OfXS?oX6JBe=;@n5j8AFjn4!i!rJT%F7nz9v6)&&aKEFd} zbN5y8zv2FvOVdr|Lh}O?(NxN^97LYK-k#%`8 zQeYpBh;Jb1XBG>{`^dmNZo^+C+q-ywiBwCB1$Dvl9Qu~g`1s6X*2V{xL}%xx%pLO~ z#Cgme%@{5_KO_j~M2&t1qlU}!p3BivF>|~SB4gu)=F5l~W5E#E50+9HZs3JU3-eYJ z_4NfAvZc%9MdmZc$Jfr5^+m)+nia#G22(2REmH0lPmYh-de}k009urccQ%@8FkEuH zXuWE)ic9CV7asgioQ_?whRQbV575pNaElkQlZs*qMI`YKntF^^-T3NOdz`dfvab^> zC>OvXv&PyavSG?r(w4z2EHexldzhpd4yk5}q~Bo5(~-oCr0H5%jFi&10Ev?hu$t!8 zJE#2l>Y2yz8q#HuSGbQ#*N^X=&MUfHd8u;Z+{Ma!c@5Y?AyKqOE?V=}b2lBgy5%hg z?-#W{C|s5(Ty?K-)ui?9tm|1*g&PuuTjatm?^YzX9=Nylz}?PYcK>;I?8TGv)=<3g z6jZX}LnhGtwQ^p=XBMt(0}LbB2|}IcO=)QGr-ykFNm0aOmi)uKhR0Gh>h^khOOx$w z3{0>6_I4iU?|B_9+p^x`nAnHEEbZ~#yYX_6N;DDMddvPzF9*S5iqz=RTLZ3w zunvVY;8el32{qa}MqirY=9bbT4>cuOm1YH679wQO)-<#zV>zc!RoOW|@D*FqVdNm2 zw)|=tdv-v>MGyz6g&hj7vR6zU5xAvI^a`*^)nJfW;ox5f?EqVUVdc*G;l2o55!`Ud zgO|l<*nbA-#osrCos`3Hx(G?`lMyKj@A3iU!~Emb6%7Y*sbG?aZ4Tx@Hk1Jz<`nxO zflb3=D?jY(LFfw)r@SZhRSe>7%8+Km#1ed3bq1EYsOm$ZZGlF`D*bbg?qtERZEMmB zcEcg~+iMC@Qp{*JBuptuKC)3p^wk{69m ztVP&*!IyBZz(R$I?zpq=Q?tdj&orG^c=7zDWr^HcIk$GQ`|gGqogIdjQ&>8_|2Lo8 zxWWo7)uxoWg_m8IT(PBl?&t1hs}(-AQT$_xK>Y2Jg63N8c5OvVmgPN%36w2$CAkeT ztuHJ12c(^UPC)~=)W8hfYRluFWlZ?#8&(m%fv@$qR7(K_ALrNROgQWpraSDXTYWR{ zyBZfIxVI%-jUT!iRk{6kWAi%8?RAb8Zl>I(#WW0X@@A6TI?U|A_3VHxSD_nf+8!jT zb#@Al8=~A;_-Y;@Vc2k>r}ls+VH(|tJXipkt)w1l;DndvYR(xs(rNi(=lf*)GmX?BC*#&PbWKmoYd+w85OWSGua&g@ z;{jw>;Dd@Hkvl|2Ks>qFBXG12wieojUdirMx9{AgI!vbxRTAO)q@UtUcWzOaryJ>~ z*XgMi5NyeW4GLis$A(89i|VZQ7Tx?FNOEtH^FQm4 zz(tMhrPv%1yFt+;j=DosioGhw<{aH$E#uFqx;H@Juv}G}sM>a~YTM0&ch^l-wa>dQ z=cCeErrRd+s^q+?A2uecx69Sr@8|6>UXQ*-t~?OWJxE$;lbpAMlvXdeu%@)maEqDY zVqAEw;%Y^r49;csH}dZD>oLEW-}GT#(qZQIn)=ptw)fXL+DtPQ)(pH6;~x$Px%4ID z`jS-iR0Cczl#0WBQhR3weRS&_=bw@CYH1&iSqi`&9KI^knA+XPkHI0_#9*-BX(Xf6~~z!E$?pqs2T^WTniRO{~k2NWzYO zF!(cS10|zB%`w5~PqvZ`RtS>7yavy##Th&`_RKmWb$u3$r^0(vuoxZOK=arD6&d?O zm^P($etc4xJYl2^Cih~R&-JikL1W{1iqSjU)ot#q!~RfMti$WDX@F4k7M!i6OXBt7 zD@6VZ1h$oD=zJBC8X_KwHDUi+w(qRRE@lzhT}k9ubYJhdhv@P+C0Bi@#Cjx}VR!Vh zzB?LD?(qcfJR0r;>bDby8RDwD-yZY_j0R$*oF;RE3Q|_E1tcX0TR#M3D#T>n@V1-oLBqMMp^x;Za1_9`Byx3@c599i#W*l|u4{>n`FvJol}8J{3QsqXjk zBAxk(3=%=F=hQhFQfO2M@;*A-2h#2-$A-{Y7d}jjfgQf&>Rp^WeLmWODtRY|77U9L z)(3}!;fT*C4p9yRME)(2cZmFw$cIG!Gm%e-d`jeVBL75$T3a+z&!9E0qLWB2kpd#i zh^!*AhDZa5Qsnc|8mdsh=Z{9kP~Rvz2+H3?8Eq%Bl?XX1GO`RO62X+;>b_bcY@z<=;rz*SDv_mQ$`| zR@k#uyC3_Il#BYkq$K?aG7@2Fd0v^_OQJZf9^k3^qzg{ARLZSbfTq?&W1wq25lYY3{&L!;i^S8}M*g(tVyxom zz1FUq{#fOPo2Cydx8g$GSMj^~g(kME2kdaek|#&pLv`ItguahRwrLSihr9Hul!D2<(V5(A!9_p0?#{EvwI7(~+;nH}!GBVwk;*!c8cR@wdaG@_ka zjA{lL?J7#RYVNse*f#I)Z1`E@PZ|^J+vN3acZ9oj@qsAh=^4`@+DmNEbl4nQ-}aE> zHXJcOaOJ)F{DtQeuBEbT=^N6-{#a9I%(e8Mt1EfuRo?~Q8y(l4zxsS^b<3@mm}k#@ z*WL$3rI&kO>zyc@-1|=8-Sv0)yQ^bIeKCK(JP@5K8Xeyappw0hra!Zf5=B7?*J?Ha z%2s|_XbyW|e)6OzzXZ z>jK{SkGyR=EVnHy+G=gLSFLTUu)kMY+vdo8-^%0seJ79j_X~NXx#MuOmAdW}+7W-J z!qMi*y0g-byLW0GZH<|CHrXl74#%#nnW_Q_4JI((0$td;HA7$$zhwc-@bQf(s2=FO zMt96)Js(+zjmGS1+H?vZ+GGx}=2(n`E%q!-rO*Yhk=g(ooGon!$douvi%XRzWauJN zuy3_tBdL6?UPdC&aAj0V_!;fqDDYiY{N$Dj1inJv5WKp;OZ^y^;QShL#>Vrh8tU&t zl4Djt%jO8Vy>2Z!?W{_R6Y_+7008`;UJ3xv@}C(V{R>?~;IGv3(~m;oF`H0CT}v0} zNV!T+p`G>WZ$TQ^tWd@E>b1>*z_4lChzZ4%yHKL%Kf9*$SqIyP78L%Y3#NE^p%f_( z?$Y)#`q>lzP>9X;ixR5N9Nl5PbNk(FibISdvQx~#$nlueZN1(^jJN|4Vk41lL;X0Sz)hlTG^RCJixt=P8XkQ$rXhgv~kO|M?_b zpt&OrE=12UxG+{h+X|;9irr+?#6HAPa%ea&?xGhZNT}G!(gf!?Pf?nDC2lBQBGN_V z1(xv8XcRu|$z7aZqxhL(SlmsSQtuJ>(Ai!hN9mGD+n>_eB#2@=HHsfD)z%bKKgHh0 z{xnuQrY-!4Xcs;2LWVT3tP`2bs;7`gXUXaVy zz0-EH;HUd;x#SH8FBZ{HvK+c_=t_Isxn|m#mvC0f&dS)5mbeoee_^5UYvGB`x7JTe zKi-00t10^F^SAQi9o=$q&-k7PFd~#+Do*T4Df51zfT>#jYPS9LG%@T{AY*>~Dw z!q8OPFuNU|eLE}G(#`JlJSeNYR`JIb6FoQhcdOr(?(DsLD)xLJ7Cb4RIyY5z{$d6s za{lwowJE~r5fcPEV8p=-2V>=%Zx-Kj$XoZvod>Yvz4|h52-kZ4xaWuGZj{|@yYjkBC5I6C$ zG2(xue)o2RN*_3aVxEwWcCvF#;l?0P?K3E z75p5Tx|3Uz=)+z7sm!G}#?8KI-g4#Ie{fKknfsZZD?=^j=DPgIQ zEfrS|CM>IE%jyT#;*ax-U)le0w);C-uUK9=ieE^2C1W~&8Gat&?yl+b>WO2qGViU* zTiFlIrs940K?95PInyir=gxkMso8X;CQ-gdE?@IG$1Xo_w-=atOc!es`PFiM_2(R2 geOk*|o#SIuma=K9^Lq!sd+>J-eQM#X<*YyaUt!?IT>t<8 diff --git a/e2e/lab/__pycache__/test_lab.cpython-313.pyc b/e2e/lab/__pycache__/test_lab.cpython-313.pyc deleted file mode 100644 index b6f9f1a3651fda792a881b24ccefee2edc5e2c8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14200 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 diff --git a/e2e/lab/__pycache__/test_mac.cpython-313.pyc b/e2e/lab/__pycache__/test_mac.cpython-313.pyc deleted file mode 100644 index a2d51ee763ea24ebcb8123c7c165cdef88ab17b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4559 zcmc&%-ES1v6~FVbyR*xhHHIX{p?Kmt*aP-DI3X^^h2W16T5uB&R!O~O81IgE2hGlG z@7(p5k_sxNn7)KiSyPq z%pN(FGvt$cTGlgqff>|olQV{%u}s^L^F^1*ImgP#Q#r$ySy|K7XI$BKSkAPw$$MyU z*ozh{olQ72@21x-TaKHobi?dCNf9_Df+qy0!#5EssshLm#z(_y2xLSJgOt<=jbPdrTZ|>oFr7H$;5rhH;zmoK!FotvfGg9fSX;(wHxluAw-n2CeWK67#M#7ceYFjx% zp2%x8D{x#@gyR}}1UH0Wm!Jy40jlAHA{@B?w+aC8W&E&?@Z6`GV=w8GMSlqE?+viH_NZ)(&9B&D*BWfk+OL1WUeoI>8PS?W!g zcWm8CG1Hz&X;ZAz&FR$WbPa2wbJ8@XQbxCtvh?v3GhC+S^>nf@<4Jv%o*&QXhrQz! zI3)e|y5^b|*wxZG)5>V3tGUc66pW0fGY#;nRj{1wvz)YUxrd<>m_nkuArR+D>6c?P z3cY(sPKYLg+u;=1J*2%7@kAVZaovTe*obbrhUB#m3GXbV=%d7=pK8;X8K=Ec0i%KP-G1j`i<|Q~~G_WzPXt z=1CW^xy=II=Kr^}RfR556-T*|IK;E=QA3ZV@&=V+vk{K+>!}P8Z%|KEX_VU}-H(^) z9vzRe%_$Fq3_}%a)lT_DbqXPHOm2=eYaiB zvC{@p+XlkvmgTM`J#!rI=z5AgwTT_*&2K@RC(HE>bD_;LW?`_j_jGCJ+oiEHrL)HE zv)1BSt28-neQLpf{1^TlQh&2Wg z-V_6{I_-jY3cTXfWq+H^H<-w z^3JCtH+Gb|&X!vBQhH)BH*=qmLH>3ApM*3X<1fYM!T{IXQsbi3cx}(M-8Y(-q=U6b z`~QdMzH(M`XWR-np__DB#x1yuJYrnwF$jo`3@z?8C1$uBzUDU#j9qx$4WapQ?VmajF^> zY7*6KZ;+K*+KoxwQhN9I%4ywhV{$sD+gU?)3e0ruUU}9sT2@mS9GTUo_(`rdpr_7R zuT^h9;=ppUCR8u1pPKDJqQnxGq5i$K79M->WH5c7Ctn0RyowG_L}z_mC}L1i#k7+# zJWiu8Rlb9oTE1<*=mX{ZT=0@l=W;79^s4XRa^mEih~={5O2?=C!r+b8Qghem+ZSIw zR(eZaY&dl(GRLi^j~&-0m!v%b;4$eBD=|;fG+WObn&!ncE$?KC7WU(shMBeeCZTB) zCUqI!9c)L_Xfu3Fai8dZ6g?=8fbgEt{Dg0&;pYIO=6De{0QCI|gBSjwwjlQ?3cu*! zt>yRR0WXGLeh?3b_C2WQL%k0qK6Kz;k`QVO+(m8lHLt@-YRWda{%aX04X*Nz>j{u) z{A-aX6>XE@u6trZXE`ry+V~s76VExO?L{&s#hB321pJNx*YFDE#f)hqU1a*WWdxTf z=@gh4(BV_x*Q2N;;@ay%fgei2o*kwt=pb0#X%P1Xj^qALhVGE)9TK}kw%j3!yF|Ds zU63v&E+j5=+^dQUz0cBo4XDvi;F(H3TU~s>ei1E4ETf)v|F@Evn?@qq=i~9l*oBYlCH>LauQ2+n{ diff --git a/e2e/lab/__pycache__/test_orchestration.cpython-313.pyc b/e2e/lab/__pycache__/test_orchestration.cpython-313.pyc deleted file mode 100644 index c553afcf677bc00eaf219e1039ae23c93d9fa19a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55580 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

swdM^y@GNHn4kqlnxlM60_PW?*$Jo~8rr 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 WSRCK1{r%cMJoK@dv*a;4`Tqf9Ri?K9 diff --git a/e2e/lab/platforms/__pycache__/_mac.cpython-313.pyc b/e2e/lab/platforms/__pycache__/_mac.cpython-313.pyc deleted file mode 100644 index ae02d9694e8e35d0c4bbd989cab00a5e4e87d673..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10430 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 Date: Tue, 10 Nov 2026 21:15:06 -0500 Subject: [PATCH 3/3] Remove my own picture's file when the call ends while it is on Co-Authored-By: Claude Sonnet 5.5 --- crates/mediad/src/picture.rs | 8 ++++++++ crates/mediad/src/picture/desktop.rs | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/crates/mediad/src/picture.rs b/crates/mediad/src/picture.rs index a14b2d796..fe0033d1 100644 --- a/crates/mediad/src/picture.rs +++ b/crates/mediad/src/picture.rs @@ -413,6 +413,14 @@ impl Canvas { } } +/// A call that ends while a picture is on (the capture thread told to stop, with nothing turned +/// off first) leaves no picture of a screen or a face behind in the temp folder. +impl Drop for Canvas { + fn drop(&mut self) { + self.forget(); + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/mediad/src/picture/desktop.rs b/crates/mediad/src/picture/desktop.rs index f321472e..54d777e7 100644 --- a/crates/mediad/src/picture/desktop.rs +++ b/crates/mediad/src/picture/desktop.rs @@ -994,6 +994,18 @@ mod tests { assert!(!next.path.exists(), "and so is the last one when the share stops"); } + #[test] + fn a_call_that_ends_while_sharing_leaves_no_picture_of_the_screen_behind() { + let mut outgoing = Outgoing::default(); + outgoing.screen_selfie.shoot(&screen()); + outgoing.selfie.shoot(&screen()); + let files = [outgoing.share_view().unwrap().path, outgoing.self_view().unwrap().path]; + assert!(files.iter().all(|file| file.exists())); + // `Video::stop` ends the capture thread without turning the share off first. + drop(outgoing); + assert!(files.iter().all(|file| !file.exists()), "{files:?}"); + } + #[test] fn openh264_is_fetched_from_cisco() { let name = library_name().unwrap_or("openh264-2.6.0-win64.dll");