Skip to content

Instantly share code, notes, and snippets.

@johnnyg
Last active July 6, 2021 19:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save johnnyg/1258881 to your computer and use it in GitHub Desktop.
Save johnnyg/1258881 to your computer and use it in GitHub Desktop.
Script to easily create (and destroy) inhibitors for gnome power events
#!/usr/bin/env python2
# Creates a new inhibitor
# While this is running the specified events will be inhibited
from optparse import OptionParser
import signal
import dbus
import sys
import os
def get_process_name(pid):
try:
f = open("/proc/%d/cmdline" % pid, "r")
name = f.read()
f.close()
except IOError:
name = ""
else:
name = name.replace('\x00', ' ')
return name
EVENTS = {
"LOGOUT": 1,
"USERSWITCH": 2,
"SUSPEND": 4,
"IDLE": 8,
}
usage = "%prog [options] <event(s)>"
description = "Creates a new inhibitor. While this is running the specified events will be inhibited."
epilog = "Valid events are %s" % ", ".join(EVENTS.keys())
parser = OptionParser(usage=usage, description=description, epilog=epilog)
parser.add_option("-n", "--name", dest="name", default=get_process_name(os.getppid()),
help="name of application that is creating the inhibitor")
parser.add_option("-r", "--reason", dest="reason", default="no reason given",
help="reason for inhibiting")
parser.add_option("-f", "--fork", action="store_true", dest="fork", default=False,
help="fork this process and print its pid")
parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True,
help="only print essential information to stdout")
parser.add_option("-s", "--silent", action="store_true", dest="silent", default=False,
help="don't print anything to stdout")
(options, args) = parser.parse_args()
if len(args) == 0:
parser.print_help()
sys.exit(1)
# Convert the events to a single int
events = 0
for arg in args:
event = arg.upper()
if event in EVENTS:
events |= EVENTS[event]
else:
parser.error("'%s' is not a valid event! %s" % (event, epilog))
# Get the SessionManager D-Bus object
bus = dbus.SessionBus()
session_manager = dbus.Interface(
bus.get_object('org.gnome.SessionManager', '/org/gnome/SessionManager'),
dbus_interface='org.gnome.SessionManager'
)
# Create args for the inhibitor
# Arg names match the D-Bus API
app_id = dbus.String(options.name)
toplevel_xid = dbus.UInt32(0)
reason = dbus.String(options.reason)
flags = dbus.UInt32(events)
# Fork if necessary
pid = os.fork() if options.fork else os.getpid()
if not options.fork or pid == 0:
# Create the inhibitor
session_manager.Inhibit(app_id, toplevel_xid, reason, flags)
if not options.silent and pid != 0:
if options.verbose:
print("Created inhibitor (app_id={}, toplevel_xid={}, reason={}, flags={})".format(
app_id, toplevel_xid, reason, flags))
msg = "Kill {} to destroy the inhibitor..."
else:
msg = "{}"
if not options.fork:
msg = "Ctrl-C or kill {} to destroy the inhibitor..."
print(msg.format(pid))
# Block until we get sent a signal or a keyboard interrupt
# We have to do this otherwise the inhibitor we just created above would be immediately destroyed
# This also the reason why dbus-send doesn't work
if not options.fork or pid == 0:
try:
signal.pause()
except KeyboardInterrupt:
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment