82 lines
2.8 KiB
Python
82 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright (c) 2026 Storm Dragon
|
|
# Authors: Storm Dragon, Angus Kola
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
"""Controlled GTK table replacement and obsolete cell event flood."""
|
|
import ctypes
|
|
import os
|
|
import sys
|
|
|
|
import gi
|
|
|
|
gi.require_version("Atk", "1.0")
|
|
gi.require_version("Gtk", "3.0")
|
|
gi.require_version("GdkX11", "3.0")
|
|
from gi.repository import Atk, GdkX11, GLib, Gtk
|
|
|
|
|
|
window = Gtk.Window(title="Table refresh probe")
|
|
window.set_default_size(400, 300)
|
|
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
window.add(box)
|
|
store = Gtk.ListStore(str)
|
|
for index in range(300):
|
|
store.append(["Original row " + str(index)])
|
|
table = Gtk.TreeView(model=store)
|
|
table.append_column(Gtk.TreeViewColumn("Row", Gtk.CellRendererText(), text=0))
|
|
table.get_accessible().set_name("Refresh results")
|
|
scroll = Gtk.ScrolledWindow()
|
|
scroll.add(table)
|
|
box.pack_start(scroll, True, True, 0)
|
|
entry = Gtk.Entry()
|
|
entry.get_accessible().set_name("After table")
|
|
box.pack_start(entry, False, False, 0)
|
|
marker = Gtk.Label(label="Marker")
|
|
marker.get_accessible().set_role(Atk.Role.ALERT)
|
|
box.pack_start(marker, False, False, 0)
|
|
window.show_all()
|
|
table.set_cursor(0)
|
|
table.grab_focus()
|
|
pendingInput = ""
|
|
signals = ctypes.CDLL(sys.argv[1])
|
|
signals.emit_refresh.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
|
|
signals.emit_refresh.restype = None
|
|
signals.refresh_bus_name.restype = ctypes.c_char_p
|
|
|
|
|
|
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.startswith("refresh "):
|
|
_, tablePath, cellPaths = command.split()
|
|
signals.emit_refresh(tablePath.encode(), cellPaths.encode())
|
|
store.clear()
|
|
for index in range(300):
|
|
store.append(["Updated row " + str(index)])
|
|
table.set_cursor(0)
|
|
# End with a real selection, without giving GTK another focus
|
|
# change to repair a lost deferred selection for us.
|
|
table.get_selection().select_path(7)
|
|
marker.set_text("Refresh complete")
|
|
elif command.startswith("select "):
|
|
table.set_cursor(int(command.split()[1]))
|
|
elif command == "entry":
|
|
entry.grab_focus()
|
|
elif command == "barrier":
|
|
entry.set_text("Focus boundary complete")
|
|
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()), signals.refresh_bus_name().decode(), flush=True) or False)
|
|
Gtk.main()
|