"""Small campaign scenarios over the same reviewed Session; no historical runner copy.""" import re,time from PIL import ImageChops from engine import * from geometry import * def init_reference(s,prefix_fillers=1): s.cmd('workspace 2');s.launch_client('reference','static-reference');rid=s.find('reference')['id'];s.cmd(f'[con_id={rid}] border none') s.cmd('workspace 1') for i in range(prefix_fillers):s.launch_client('filler'+str(i),'static-reference') s.cmd('layout mosaic' if s.spec['mode']=='mosaic' else 'layout splith') return rid def stable_reference(s): s.inject('move',[s.outputs[0]['logical'][0]+10,s.outputs[0]['logical'][1]+590]);time.sleep(.15) a=s.capture('H2-reference1','HEADLESS-2');time.sleep(.6);b=s.capture('H2-reference2','HEADLESS-2');exact(a,b) need(all(v==(48,48,56) for v in a.get_flattened_data()),'static uniform H2');s.save('reference-stability',dict(status='PASS',exact=exact(a,b)));return a def marker_host_baseline(s): """D3-only pre-XDG association: source + creation timing + cardinality. This does not observe native owner IDs or host child count. No root is selected by clip/index after the owner exists. """ from transition import observed_epochs need(s.spec.get('marker',False) and s.spec['mode']=='mosaic' and 'owner' not in s.proc,'prospective pre-owner marker baseline') marker=s.proc.get('marker-background');need(marker is not None and marker.poll() is None,'live marker layer client') start=next(e['ns'] for e in s.events if e['kind']=='spawn' and e['name']=='marker-background') end=time.monotonic_ns();trace=s.log('compositor') creations=[l for l in trace.splitlines() if 'new layer surface: namespace ' in l] need(len(creations)==1 and 'namespace wallpaper layer 0 ' in creations[0],'one wallpaper layer creation') snapshot=s.snapshot('pre-XDG-marker-host') need(not any(n.get('app_id')=='org.mosaic.NestedGrabProbe' for n in nodes(snapshot['tree'])),'no popup owner before baseline') epochs=observed_epochs(trace,'HEADLESS-1',start,end);tree=None;observed=[] for e in epochs: need(e['scene'] is not None,'complete baseline callback') roots=e['roots'] if not roots: need(tree is None,'marker host disappeared before owner');continue need(len(roots)==1,'unique pre-XDG host') r=roots[0] need(r.get('local_index')=='1' and r.get('enabled')=='1' and r.get('clip_valid')=='0' and r.get('clip')=='0,0,0,0','source-backed ordinary layer host') if tree is None:tree=r['tree'] need(r['tree']==tree,'stable pre-XDG host') observed.append(e) need(len(observed)>=2,'two complete pre-XDG host observations') baseline=dict(tree=tree,window=[start,end],epochs=epochs,layer_creation=creations[0],marker_pid=marker.pid,snapshot=snapshot, correlation='single layer constructor + pre-owner timing + stable cardinality; no native layer ID or child count') s.save('marker-host-baseline',baseline);s.marker_host=baseline return baseline def associated_root(roots,baseline=None,commit_ns=None): if baseline is None: need(len(roots)==1 and roots[0].get('local_index')=='1','unique first popup root');return roots[0] need(commit_ns is not None and commit_ns>baseline['window'][1],'root callback after pre-XDG baseline') need(len(roots)==2 and len({r.get('tree') for r in roots})==2,'one known layer host plus one new XDG root') need([r.get('local_index') for r in roots]==['1','2'],'native host order retained') known=[r for r in roots if r.get('tree')==baseline['tree']] need(len(known)==1 and known[0].get('enabled')=='1' and known[0].get('clip_valid')=='0' and known[0].get('clip')=='0,0,0,0','same unchanged known layer host') return next(r for r in roots if r['tree']!=baseline['tree']) def root_state(s,state,origin,window_start,expect_hidden=False,previous=None,expected_tree=None): from transition import observed_epochs from ipc_predicates import ancestry end=time.monotonic_ns();output=state['workspace']['output'] out=next(o['logical'] for o in s.outputs if o['name']==output) need(state['workspace']['layout']=='mosaic' and origin==state['origin'],'current Mosaic origin') path=ancestry(state['snapshot']['tree'],state['owner']['id']) need(path and path[-1]['id']==state['owner']['id'],'exact IPC owner ancestry') need([n['id'] for n in path if n.get('type')=='workspace']==[state['workspace']['id']] and [n['name'] for n in path if n.get('type')=='output']==[output],'exact workspace output ancestry') live=[n for n in nodes(state['snapshot']['tree']) if n.get('app_id')==state['owner']['app_id'] and n.get('visible')] need(len(live)==1 and live[0]['id']==state['owner']['id'],'unique live XDG owner') prot=protocol(s.log('owner'));need(len(prot['grabs'])==2,'two real grabs') epochs=observed_epochs(s.log('compositor'),output,window_start,end) rows=[];trees=set();applied=False for e in epochs: c,sc,roots=e['commit'],e['scene'],e['roots'] need(c.get('has_buffer') in ('0','1') and sc is not None and sc.get('workspace')==str(state['workspace']['id']) and sc.get('layout')=='5','complete current callback workspace/layout') owners=[o for o in e['owners'] if o.get('id')==str(state['owner']['id'])] need(len(owners)==1 and owners[0].get('scene_valid')=='1','exact applied owner') r=associated_root(roots,getattr(s,'marker_host',None),int(c['ns'])) o=owners[0];trees.add(r['tree']) need(len(trees)==1 and (expected_tree is None or r['tree']==expected_tree),'same live root') need(int(c['ns'])