Skip to content

Instantly share code, notes, and snippets.

@rochacbruno
Last active October 20, 2025 14:43
Show Gist options
  • Select an option

  • Save rochacbruno/20a660e282b47f3b6ad40ffc4f03f5cf to your computer and use it in GitHub Desktop.

Select an option

Save rochacbruno/20a660e282b47f3b6ad40ffc4f03f5cf to your computer and use it in GitHub Desktop.
gpu-screen-recorder with systray icon
#!/usr/bin/env python3
import subprocess
import gi
import signal
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, AppIndicator3
APP_ID = "gpu.screen.recorder"
RECORD_CMD = ["bash", "-c", "gpu-screen-recorder", "-o", "/tmp/output.mp4"]
class RecorderTray:
def __init__(self):
self.indicator = AppIndicator3.Indicator.new(
APP_ID,
"media-record",
AppIndicator3.IndicatorCategory.APPLICATION_STATUS
)
self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
self.indicator.set_menu(self.build_menu())
# Start recorder
self.proc = subprocess.Popen(RECORD_CMD)
# Watch for process exit
GLib.timeout_add(1000, self.check_process)
def build_menu(self):
menu = Gtk.Menu()
stop_item = Gtk.MenuItem(label="Stop Recording")
stop_item.connect("activate", self.stop_recording)
menu.append(stop_item)
quit_item = Gtk.MenuItem(label="Quit")
quit_item.connect("activate", self.quit)
menu.append(quit_item)
menu.show_all()
return menu
def check_process(self):
ret = self.proc.poll()
if ret is not None:
Gtk.main_quit()
return False
return True
def stop_recording(self, _):
self.proc.terminate()
Gtk.main_quit()
def quit(self, _):
self.stop_recording(_)
def main():
signal.signal(signal.SIGINT, signal.SIG_DFL)
RecorderTray()
Gtk.main()
if __name__ == "__main__":
from gi.repository import GLib
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment