#!/usr/bin/env python3 # Copyright (c) 2026 Storm Dragon # Authors: Storm Dragon, Angus Kola # SPDX-License-Identifier: GPL-3.0-or-later """A panel popup and an editor on separate AT-SPI providers, for private tests.""" import ctypes import os import sys import gi gi.require_version("Gtk", "3.0") gi.require_version("Atk", "1.0") gi.require_version("Gdk", "3.0") gi.require_version("GdkX11", "3.0") from gi.repository import Atk, Gdk, GdkX11, GLib, Gtk processName = sys.argv[1] GLib.set_prgname("editor" if processName == "editor" else "mate-panel") if ctypes.CDLL(None).prctl(15, processName.encode(), 0, 0, 0) != 0: raise RuntimeError("cannot set fixture process name") window = Gtk.Window(title="Panel menu fixture " + processName) window.set_default_size(400, 150) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) window.add(box) entry = Gtk.Entry() entry.get_accessible().set_name("Editor entry") box.pack_start(entry, False, False, 0) button = Gtk.Button(label="Applications") box.pack_start(button, False, False, 0) barrier = Gtk.Label() barrier.get_accessible().set_role(Atk.Role.ALERT) box.pack_start(barrier, False, False, 0) for iconName, description, parentRole, parentName in ( ("", "", Atk.Role.PANEL, "Network applet"), ("Named icon", "", Atk.Role.PANEL, "Unused applet name"), ("", "Icon description", Atk.Role.PANEL, "Unused applet name"), ("", "", Atk.Role.FILLER, "Unrelated container"), ): parent = Gtk.Box() parent.get_accessible().set_role(parentRole) parent.get_accessible().set_name(parentName) icon = Gtk.Image.new_from_icon_name("network-workgroup", Gtk.IconSize.MENU) icon.get_accessible().set_role(Atk.Role.ICON) icon.get_accessible().set_name(iconName) icon.get_accessible().set_description(description) parent.add(icon) box.pack_start(parent, False, False, 0) if processName != "editor": window.set_accept_focus(False) window.set_focus_on_map(False) window.show_all() Atk.get_root().set_name("editor" if processName == "editor" else "mate-panel") menu = Gtk.Menu() firstItem = Gtk.MenuItem(label="First application") menu.append(firstItem) submenuItem = Gtk.MenuItem(label="Utilities") submenu = Gtk.Menu() submenu.append(Gtk.MenuItem(label="Example utility")) submenuItem.set_submenu(submenu) menu.append(submenuItem) menu.append(Gtk.MenuItem(label="Last application")) menu.show_all() pendingInput = "" def receive_command(_source, _condition): global pendingInput content = os.read(sys.stdin.fileno(), 4096) if not content: Gtk.main_quit() return False pendingInput += content.decode() while "\n" in pendingInput: command, pendingInput = pendingInput.split("\n", 1) if command == "popup": menu.popup_at_widget(button, Gdk.Gravity.SOUTH_WEST, Gdk.Gravity.NORTH_WEST, None) elif command == "close": menu.popdown() elif command == "ordinary": window.get_accessible().emit("activate") elif command == "stale": firstItem.get_accessible().notify_state_change(Atk.StateType.FOCUSED, True) barrier.set_text("Stale barrier") elif command.startswith("edit "): entry.set_text(command.removeprefix("edit ")) entry.grab_focus() elif command == "quit": Gtk.main_quit() return False return True GLib.io_add_watch(sys.stdin, GLib.IO_IN | GLib.IO_HUP, receive_command) GLib.idle_add(lambda: print("ready", GdkX11.X11Window.get_xid(window.get_window()), flush=True) or False) Gtk.main()