Files
cthulhu/tests/gtk_panel_menu.py

98 lines
3.5 KiB
Python

#!/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()