#!/usr/bin/env python3 # Copyright (c) 2026 Storm Dragon # Authors: Storm Dragon, Angus Kola # SPDX-License-Identifier: GPL-3.0-or-later """GTK4 fixture emitting AT-SPI announcement events on stdin commands. Commands (one per line): announce polite announce assertive """ import os import sys import gi gi.require_version("Gtk", "4.0") gi.require_version("GdkX11", "4.0") from gi.repository import GdkX11, GLib, Gtk pendingInput = "" window = Gtk.Window(title="Announcement fixture") window.set_default_size(320, 200) label = Gtk.Label(label="Announcement fixture") window.set_child(label) window.present() def receive_command(_source, _condition): global pendingInput content = os.read(sys.stdin.fileno(), 4096) if not content: loop.quit() return False pendingInput += content.decode() while "\n" in pendingInput: command, pendingInput = pendingInput.split("\n", 1) parts = command.split(" ", 2) if len(parts) == 3 and parts[0] == "announce": priority = Gtk.AccessibleAnnouncementPriority.MEDIUM if parts[1] == "assertive": priority = Gtk.AccessibleAnnouncementPriority.HIGH window.announce(parts[2], priority) print("announced", parts[2], flush=True) return True GLib.io_add_watch(sys.stdin.fileno(), GLib.PRIORITY_DEFAULT, GLib.IO_IN, receive_command) def announce_ready(): surface = window.get_surface() xid = GdkX11.X11Surface.get_xid(surface) print("ready", xid, flush=True) return False GLib.timeout_add(250, announce_ready) loop = GLib.MainLoop() loop.run()