diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 23:41:31 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-13 23:41:31 +0300 |
| commit | 76073fe5fad8799e5850805f2f090af2cb62c741 (patch) | |
| tree | 9658019babe4760a3634bdab4da0731a10e42e68 /tests/helpers/run_surfaces.py | |
| parent | dd1775a9927922c14f8679ccbc4d3ca8d5917e20 (diff) | |
Simplify the public event and CPU API
Applications now need far less ceremony: hello.c is a 20-line loop that
handles REFRESH, CLOSE and QUIT and draws into the surface's own pixels.
- Fold GEOMETRY, STATE and FOCUS into one WINDOW event carrying size,
scale and state; unchanged values send nothing.
- Guarantee REFRESH once a window has a size and after every resize,
never at size zero.
- Merge DROP_HOVER into DROP with over/leave/data actions and give drag
and drop actions enums.
- Keep event strings valid until the next wait and drop
yasl_event_release; empty or failed waits report NONE.
- Replace copy-in presentation with a lent pixel buffer:
yasl_cpu_pixels and yasl_cpu_present.
- Remove yasl_poll_event, yasl_cpu_read_pixels, unused event fields and
comments that restated names.
- Wayland: resize floating windows in request_size instead of reporting
it unsupported, and stop marking new GPU surfaces as Vulkan so
yasl_vulkan_create_surface no longer fails with NATIVE_WINDOW_IN_USE.
Also includes the in-progress public API refactor that was uncommitted
in the tree (removal of the app/loop layer, new surface, GL and Vulkan
entry points).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'tests/helpers/run_surfaces.py')
| -rw-r--r-- | tests/helpers/run_surfaces.py | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/tests/helpers/run_surfaces.py b/tests/helpers/run_surfaces.py new file mode 100644 index 0000000..f120e35 --- /dev/null +++ b/tests/helpers/run_surfaces.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +"""Run the public surface/GPU contract tests on private Weston and Xwayland.""" +import os +from pathlib import Path +import subprocess +import sys +import tempfile +import time + +def wait_for(process, ready): + deadline = time.monotonic() + 12 + while time.monotonic() < deadline: + if process.poll() is not None: + raise RuntimeError('Display server stopped before readiness') + if ready(): + return + time.sleep(0.02) + raise TimeoutError('Display server readiness') + +def main(): + weston, xwayland, contract, hello, tablet, gl, vulkan, notepad = sys.argv[1:] + servers = [] + with tempfile.TemporaryDirectory(prefix='yasl-surfaces-') as directory: + root = Path(directory) + env = os.environ.copy() + env.pop('WAYLAND_SOCKET', None) + env.update(XDG_RUNTIME_DIR=directory, WAYLAND_DISPLAY='yasl-test', + XDG_SESSION_TYPE='wayland', LIBGL_ALWAYS_SOFTWARE='1') + lavapipe = next(Path('/usr/share/vulkan/icd.d').glob('*lvp*.json'), None) + if lavapipe: + env['VK_DRIVER_FILES'] = str(lavapipe) + with (root/'weston.log').open('w+') as wl_log, (root/'xwayland.log').open('w+') as x_log: + try: + wl = subprocess.Popen([weston, '--backend=headless', '--renderer=gl', + '--socket=yasl-test', '--idle-time=0', '--no-config', + '--width=1024', '--height=768'], env=env, stdout=wl_log, stderr=wl_log) + servers.append(wl) + wait_for(wl, lambda: (root/'yasl-test').is_socket()) + display_file = root/'display' + with display_file.open('w') as fd: + x = subprocess.Popen([xwayland, '-displayfd', str(fd.fileno()), + '-shm', '-noreset', '-nolisten', 'tcp'], env=env, + pass_fds=(fd.fileno(),), stdout=x_log, stderr=x_log) + servers.append(x) + wait_for(x, lambda: bool(display_file.read_text().strip())) + env['DISPLAY'] = ':' + display_file.read_text().strip() + for backend in ('wayland', 'x11'): + case = env.copy() + if backend == 'x11': + case.pop('WAYLAND_DISPLAY', None) + case['XDG_SESSION_TYPE'] = 'x11' + for binary, args in ((contract,[backend]), (gl,[backend]), + (vulkan,[backend]), (tablet,['--backend',backend,'--smoke-test']), + (notepad,['--smoke-test'])): + if binary == '-': + continue + print('Testing', Path(binary).name, backend, flush=True) + subprocess.run([binary, *args], env=case, check=True, timeout=15) + # hello runs until closed: it must survive its first frames. + if hello == '-': + continue + print('Testing', Path(hello).name, backend, flush=True) + process = subprocess.Popen([hello], env=case) + try: + process.wait(timeout=1) + raise RuntimeError(f'{Path(hello).name} exited with {process.returncode}') + except subprocess.TimeoutExpired: + process.terminate() + process.wait() + except BaseException: + for log in (wl_log,x_log): + log.flush();log.seek(0);print(log.read(), file=sys.stderr) + raise + finally: + for server in reversed(servers): + server.terminate() + try: + server.wait(timeout=5) + except subprocess.TimeoutExpired: + server.kill();server.wait() +if __name__ == '__main__': + main() |
