"""A small but real GTK desktop: the fixture for the daily-usage evaluation. It is not a toy widget gallery - it is the set of controls a person actually meets: a menu bar with a submenu, a text entry, buttons, a scrolling list, a status bar, and a second window. Every interaction is appended to a JSON marker file, so the evaluation can verify a task by the *application's own* record of what happened rather than by asking the agent whether it thinks it succeeded. """ import json import pathlib import sys import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk # noqa: E402 MARKER = pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else "/tmp/gtk_daily.json") READY = pathlib.Path(str(MARKER) + ".ready") def record(**event): history = json.loads(MARKER.read_text()) if MARKER.exists() else [] history.append(event) MARKER.write_text(json.dumps(history)) class Everyday(Gtk.Application): def __init__(self): # one instance per marker, or GTK forwards a second launch to the first # and the new window never appears - which silently mis-runs an evaluation super().__init__(application_id=f"dev.tinycomputeragent.daily.{MARKER.stem}") self.connect("activate", self.on_activate) self.status = None self.entry = None def on_activate(self, app): window = Gtk.ApplicationWindow(application=app, title="Everyday") window.move(160, 160) window.set_default_size(620, 430) column = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) window.add(column) self.status = Gtk.Label(label="ready") self.status.set_xalign(0) menubar = Gtk.MenuBar() file_item = Gtk.MenuItem(label="File") menubar.append(file_item) submenu = Gtk.Menu() file_item.set_submenu(submenu) for label in ("New", "Save As...", "Quit"): item = Gtk.MenuItem(label=label) item.connect("activate", self.on_menu, label) submenu.append(item) column.pack_start(menubar, False, False, 0) self.entry = Gtk.Entry() self.entry.set_text("report.txt") self.entry.get_accessible().set_name("File name") # so the index can click it padding = Gtk.Box(spacing=6) padding.pack_start(Gtk.Label(label="File name"), False, False, 0) padding.pack_start(self.entry, True, True, 0) column.pack_start(padding, False, False, 6) buttons = Gtk.Box(spacing=8) for label in ("Save", "Cancel", "Settings", "Terminal"): button = Gtk.Button(label=label) button.set_size_request(104, 38) button.connect("clicked", self.on_button, label) buttons.pack_start(button, False, False, 0) column.pack_start(buttons, False, False, 6) scroller = Gtk.ScrolledWindow() scroller.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scroller.set_size_request(560, 150) listing = Gtk.ListBox() for index in range(1, 25): row = Gtk.ListBoxRow() row.add(Gtk.Label(label=f"Item {index:02d}", xalign=0)) listing.add(row) listing.connect("row-activated", self.on_row) scroller.add(listing) column.pack_start(scroller, True, True, 0) column.pack_start(self.status, False, False, 4) window.show_all() window.connect("key-press-event", self.on_key) READY.write_text("mapped") # -- the app's own record of what happened -------------------------------- def note(self, text): self.status.set_text(text) def on_button(self, button, label): entry_text = self.entry.get_text() if self.entry is not None else "" record(action="button", label=label, entry=entry_text) self.note("pressed " + label) if label == "Settings": self.open_settings() def on_menu(self, item, label): record(action="menu", label=label) self.note("menu " + label) def on_row(self, listing, row): label = row.get_child().get_text() if row.get_child() else "" record(action="row", label=label) self.note("row " + label) def on_key(self, widget, event): from gi.repository import Gdk if event.state & Gdk.ModifierType.CONTROL_MASK and event.keyval == Gdk.KEY_s: record(action="shortcut", label="ctrl+s", entry=self.entry.get_text()) self.note("saved by shortcut") return True return False def open_settings(self): window = Gtk.Window(title="Settings") window.set_default_size(320, 180) window.move(840, 200) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8) window.add(box) for label in ("Apply", "Close"): button = Gtk.Button(label=label) button.connect("clicked", self.on_button, label) box.pack_start(button, False, False, 0) window.show_all() app = Everyday() sys.exit(app.run([]))