#!/usr/bin/env python3 # 5 taps in the top-right corner of the screen close Chromium (kiosk). # Run from session autostart. Requires: python3, PyGObject (Gtk), Wayland or X11. import subprocess import sys try: import gi gi.require_version("Gdk", "3.0") gi.require_version("Gtk", "3.0") from gi.repository import Gdk, Gtk, GLib except Exception as e: sys.stderr.write("five-tap-close-chromium: need PyGObject Gtk: %s\n" % e) sys.exit(1) CORNER_SIZE = 80 TAP_WINDOW_SEC = 2.0 CHROMIUM_KILL_CMD = ["pkill", "-f", "chromium"] def get_screen_size(): display = Gdk.Display.get_default() if not display: return 800, 1280 monitor = display.get_monitor(0) if display.get_n_monitors() else None if monitor: geom = monitor.get_geometry() return geom.width, geom.height return 800, 1280 def on_button_press(widget, event, data): count, reset_timer = data count[0] += 1 if reset_timer[0]: GLib.source_remove(reset_timer[0]) if count[0] >= 5: count[0] = 0 try: subprocess.run(CHROMIUM_KILL_CMD, timeout=2, capture_output=True) except Exception: pass if reset_timer[0]: GLib.source_remove(reset_timer[0]) reset_timer[0] = None return def reset(): count[0] = 0 reset_timer[0] = None return False reset_timer[0] = GLib.timeout_add(int(TAP_WINDOW_SEC * 1000), reset) return False def main(): win = Gtk.Window() win.set_decorated(False) win.set_resizable(False) win.set_default_size(CORNER_SIZE, CORNER_SIZE) win.set_skip_taskbar_hint(True) win.set_skip_pager_hint(True) win.set_keep_above(True) win.set_opacity(0.01) win.set_accept_focus(False) win.set_focus_on_map(False) # Allow closing from compositor / taskbar win.connect("destroy", Gtk.main_quit) # Count 5 taps count = [0] reset_timer = [None] win.connect("button-press-event", on_button_press, (count, reset_timer)) # Touch events often come as button-press with button=1 win.set_events( win.get_events() | Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.TOUCH_MASK ) win.realize() # Position top-right (after realization so we have a display) w, h = get_screen_size() x = max(0, w - CORNER_SIZE) win.move(x, 0) win.show_all() Gtk.main() if __name__ == "__main__": main()