"""EXPERIMENTAL comparable nonleaf fullscreen, whole-field predictions first.""" import re,time from PIL import ImageDraw import cases,validators from engine import COLORS from geometry import need,crossing,solid_point,exact,count from ipc_predicates import ancestry from model import Provenance from predicates import geometry def group_candidate(state,peer_id,group_id,fullscreen=True,applied=None): # WHY: IPC serializes pending.fullscreen_mode, workspace marker is always1. # CONTRACT: never turn that field into a direct current-state observation. # INVARIANT: sampled applied qualification requires post-command configure / # ACK / MAP plus measured geometry; native current bit remains NOT_OBSERVABLE. path=ancestry(state['snapshot']['tree'],state['owner']['id']) rows=[n for n in path[:-1] if n.get('type')=='con' and n.get('id')==group_id] need(len(rows)==1,'actual nonleaf group absent');group=rows[0] need(group.get('fullscreen_mode',0)==int(fullscreen),'group fullscreen IPC candidate mismatch') need(group.get('layout')=='splith' and len(group.get('nodes',[]))==2,'exact horizontal two-child group') need({n['id'] for n in group['nodes']}=={state['owner']['id'],peer_id},'owner/peer must be direct children') need(not group.get('floating_nodes') and not any((n.get('floating') or '').endswith('on') for n in group['nodes']),'floating group child') if fullscreen: out=next(o for o in state['snapshot']['outputs'] if o['name']==state['workspace']['output'])['rect'] need(group['rect']==out,'fullscreen group does not cover output') need(out['width']==800 and [n['rect']['width'] for n in group['nodes']]==[400,400],'fullscreen measured400/400 required') need(applied and applied.get('source')=='post-command-xdg-configure-ack-map' and applied.get('group_id')==group_id and applied.get('owner_id')==state['owner']['id'] and applied.get('workspace_id')==state['workspace']['id'],'pending-only ancestor is not sampled applied evidence') return group def applied_configure(raw,cut,owner_id,workspace_id,group_id): tail=raw[cut:] configs=re.findall(r'TOPLEVEL XDG_CONFIGURE serial=(\d+) ack',tail) need(configs and 'TOPLEVEL MAP ' in tail,'post-fullscreen configure/ACK/map absent') # Actual wire association and SHM mapping are independently parsed by grab(). need(re.search(r'xdg_surface#\d+\.ack_configure\('+configs[-1]+r'\)',tail),'post-fullscreen actual ACK wire absent') return dict(source='post-command-xdg-configure-ack-map',group_id=group_id,owner_id=owner_id,workspace_id=workspace_id,serial=int(configs[-1]),native_current_bit='NOT_OBSERVABLE') def positioner_adjust(raw): values=[] for popup in ('POPUP_A','POPUP_B'): ids=re.search(rf'{popup} CREATE wl=(\d+) xdg=(\d+) role=(\d+)',raw);need(ids is not None,'popup role absent') create=re.search(rf'xdg_surface#{ids[2]}\.get_popup\(new id xdg_popup#{ids[3]}, xdg_surface#\d+, xdg_positioner#(\d+)\)',raw);need(create is not None,'actual positioner absent') # IDs may be reused after destroy: bind the latest positioner declaration # and all setters before this exact get_popup request. before=raw[:create.start()];decl=list(re.finditer(rf'create_positioner\(new id xdg_positioner#{create[1]}\)',before));need(decl,'positioner creation wire absent') segment=before[decl[-1].start():] adjust=re.findall(rf'xdg_positioner#{create[1]}\.set_constraint_adjustment\((\d+)\)',segment) need(adjust==['0'],'different/unobserved positioner adjustment');values.append(int(adjust[0])) return values def comparable(pristine,core): for r in (pristine,core): need(r.get('fresh') and crossing(r['popup_A'],0,0) and crossing(r['popup_B'],0,0),'actual fresh crossing not exercised') need(r['child_widths']==[400,400] and r['applied']['source']=='post-command-xdg-configure-ack-map','pending/noncomparable group') keys=('client_sha256','client_source_sha256','protocol_sha256','positioner_adjust','roles','top_configure','child_rects','child_widths','group_rect','popup_A','popup_B','configured_A','configured_B','origin','outputs') need(all(pristine[k]==core[k] for k in keys),'pristine/core source/role/actual geometry differs') return dict(status='PARTIALLY_FEASIBLE',native_current_bit='NOT_OBSERVABLE',atomic_current_state='NOT_PROVEN') def expected_h2(baseline,g,output,frame,colors,active_roles=('POPUP_A','POPUP_B'),require_crossing=False): # WHY/CONTRACT/INVARIANT: predict whole RGB before acquisition. Standard / # fullscreen popup overflow is composed A then B, without a learned mask. need(frame=='logical' and output['scale']==1 and output['transform']=='normal','unsupported H2 frame') ox,oy,ow,oh=output['logical'];need(baseline.size==(ow,oh),'H2 baseline size') expected=baseline.copy();draw=ImageDraw.Draw(expected);parent=g['origin'] for key,name in (('A','POPUP_A'),('B','POPUP_B')): cfg=g['configured_'+key];rect=g[key] need(len(cfg)==4 and cfg[2]>0 and cfg[3]>0 and rect==[parent[0]+cfg[0],parent[1]+cfg[1],cfg[2],cfg[3]],'actual configure/global rectangle differs') if require_crossing:need(crossing(rect,0,0),'actual popup noncrossing') l,t,r,b=max(rect[0],ox),max(rect[1],oy),min(rect[0]+rect[2],ox+ow),min(rect[1]+rect[3],oy+oh) if name in active_roles and l1; peer is created on ws3, then explicitly inserted # in the marked nonleaf group. No post-failure empirical repair is allowed. s.debit('chain');s.launch_client('owner','fullscreen-client','fullscreen_cross') oid=s.find('owner')['id'];s.cmd(f'[con_id={oid}] focus');s.cmd(f'[con_id={oid}] split h') path=ancestry(s.snapshot('group-wrapper')['tree'],oid);group=path[-2] need(group.get('type')=='con' and [n['id'] for n in group.get('nodes',[])]==[oid],'split did not create owner wrapper') gid=group['id'];s.cmd(f'[con_id={gid}] mark --add smx-followup-group') s.cmd('workspace 3');s.launch_client('fullscreen-peer','static-reference');peer=s.find('fullscreen-peer')['id'] s.cmd(f'[con_id={peer}] move container to mark smx-followup-group');s.cmd('workspace 1');s.cmd(f'[con_id={oid}] focus') snap=s.snapshot('fullscreen-before');path=ancestry(snap['tree'],oid) group=next(n for n in path if n.get('id')==gid) need({n['id'] for n in group.get('nodes',[])}=={oid,peer},'peer outside exact owner group') return oid,peer,gid def run(s): cases.init_reference(s,1) try:oid,peer,gid=prepare_group(s) except ValueError as exc: s.save('fullscreen-not-exercised',dict(status='NOT_EXERCISED',reason=str(exc)));return 'NOT_EXERCISED' baseline=cases.stable_reference(s);cut=len(s.log('owner')) s.cmd(f'[con_id={gid}] fullscreen enable');s.cmd(f'[con_id={oid}] focus') s.wait(lambda:'TOPLEVEL XDG_CONFIGURE ' in s.log('owner')[cut:] and 'TOPLEVEL MAP ' in s.log('owner')[cut:]);time.sleep(.2) state=s.owner('owner');applied=applied_configure(s.log('owner'),cut,oid,state['workspace']['id'],gid) group=group_candidate(state,peer,gid,applied=applied) top=s.capture('fullscreen-owner','HEADLESS-1');xy=solid_point(top,COLORS['TOPLEVEL'],s.outputs[0],'logical',[*state['origin'],420,320]) ta,ba=s.click('owner',xy,'left',True);s.wait(lambda:'POPUP_A MAP ' in s.log('owner')) root=s.capture('fullscreen-A','HEADLESS-1');xyA=solid_point(root,COLORS['POPUP_A'],s.outputs[0],'logical') tb,bb=s.click('owner',xyA,'left',True);s.wait(lambda:'POPUP_B MAP ' in s.log('owner'));time.sleep(.2) p=validators.grab(s.log('owner'));adjust=positioner_adjust(s.log('owner'));g=fresh_geometry(s,state) s.delivery('owner',[*state['origin'],420,320],xy,ta,ba,'TOPLEVEL',p['grabs'][0]['serial']);s.delivery('owner',g['A'],xyA,tb,bb,'POPUP_A',p['grabs'][1]['serial']) if not all(crossing(g[k],0,0) for k in ('A','B')): s.save('fullscreen-not-exercised',dict(status='NOT_EXERCISED',geometry=g));return 'NOT_EXERCISED' images=measured_pair(s,'fullscreen-mapped',baseline,g,cross=True);input_target(s,images,g,'POPUP_B','B') m=__import__('json').loads(__import__('pathlib').Path(s.auth['manifest']).read_text()) record=dict(client_sha256=s.auth['client_binary_sha256'],client_source_sha256=m['files']['graphics/clients/fullscreen-client.c'],protocol_sha256=m['files']['graphics/protocols/xdg-shell.xml'],positioner_adjust=adjust,fresh=True,applied=applied,roles=p['hierarchy'],top_configure=re.findall(r'TOPLEVEL ROLE_CONFIGURE w=(\d+) h=(\d+)',s.log('owner'))[-1],child_rects=[c['rect'] for c in group['nodes']],child_widths=[c['rect']['width'] for c in group['nodes']],group_rect=group['rect'],popup_A=g['A'],popup_B=g['B'],configured_A=g['configured_A'],configured_B=g['configured_B'],origin=g['origin'],outputs=s.outputs,owner_id=oid,group_id=gid,peer_id=peer,protocol=p) s.save('fullscreen-comparability',record) before=s.log('owner');start=time.monotonic_ns();s.client_cmd('owner','close_b','COMMAND close_b DONE') from lifecycle import explicit_child_close explicit_child_close(before,s.log('owner'),p['ids'],start,time.monotonic_ns());time.sleep(.15) state=s.owner('owner');group_candidate(state,peer,gid,applied=applied);g=fresh_geometry(s,state) images=measured_pair(s,'fullscreen-B-closed',baseline,g,('POPUP_A',));need(not any(count(im,COLORS['POPUP_B']) for im in images),'B residual');input_target(s,images,g,'POPUP_A','A') s.cmd(f'[con_id={gid}] fullscreen disable',True);s.cmd(f'[con_id={state["workspace"]["id"]}] layout splith',True);s.expected_layout='splith';time.sleep(.35) state=s.owner('owner');need(state['owner']['id']==oid,'owner changed on standard return');group_candidate(state,peer,gid,fullscreen=False) g=fresh_geometry(s,state);images=measured_pair(s,'fullscreen-standard-A',baseline,g,('POPUP_A',));input_target(s,images,g,'POPUP_A','A') s.close_client('owner',scenario='nested');final=s.pair_capture('fullscreen-final');exact(baseline,final[1]) return 'PARTIALLY_FEASIBLE'