Skip to content

Instantly share code, notes, and snippets.

@CyberShadow
Last active October 28, 2024 07:25
Show Gist options
  • Select an option

  • Save CyberShadow/aaacbd456efa6e4b6886d453beea9a86 to your computer and use it in GitHub Desktop.

Select an option

Save CyberShadow/aaacbd456efa6e4b6886d453beea9a86 to your computer and use it in GitHub Desktop.
My Blankie configuration
# Sample Blankie configuration file.
# The main duty of thes configuration file is to define a function,
# config, which configures Blankie according to the current
# circumstances. Using the provided configuration object, the
# function tells Blankie what state the system should be in, and
# Blankie takes care to apply any changes necessary to bring the
# system to that state.
# This function is re-evaluated every time the context (idle time /
# power / lock screen status) changes, so we can use conditionals here
# to customize the behavior.
# All functionality in Blankie is provided by modules. The
# configuration function dictates which modules should be running at
# any given time.
#
# Modules are generally divided into three categories:
#
# - Modules which should run always, along with Blankie.
# These generally provide events that blankie reacts to.
#
# Blankie automatically registers some built-in on_start modules to
# provide core functionality, such as reacting to the system being
# idle for some time.
#
# - Modules which should run once the session has been idle for a
# certain amount of time.
#
# These modules are usually added conditionally, in an `if
# c.is_idle_for(N):` block, where N is a number of seconds since the
# last user input. Can be used to activate the lock screen or
# perform power actions after inactivity.
#
# If the system is about to be incapacitated (suspended or
# hibernated), Blankie starts all on_idle hooks (as if the system has
# been idle for an infinite amount of time).
#
# - Modules which should run when the lock screen activates (whether
# due to a configured idle timeout or explicit user request).
#
# Good for enabling additional security to further lock down the
# machine until it is unlocked. The lock screen program itself is
# also registered here.
# Here is a very simple configuration, which uses just two modules.
# It locks the screen after 15 minutes with i3lock.
# def config(c):
# if c.is_idle_for(15 * 60):
# c.run_module("lock")
# if c.is_locked():
# c.run_module("i3lock")
# Below is a more elaborate configuration, which is close to the
# author's personal Blankie configuration.
import os
import os.path
import pathlib
import socket
import subprocess
import blankie
def config(c):
hostname = socket.gethostname()
is_home = hostname.split(".")[0] == "home"
is_main_user = os.getuid() == 1000
is_unattended = os.path.exists(os.path.expanduser("~/.unattended"))
# Let's define some helper variables first.
# We want a much shorter delay if the lock screen is already active.
if not c.is_locked():
# Settings for when the lock screen is not active.
# We can have different settings for different machines by
# checking the hostname.
if is_home:
# A longer timeout on the desktop PC.
delay = 10 * 60
else:
# A shorter timeout on other machines (laptops).
delay = 5 * 60
# Lock screen after 5 or 10 minutes
action = ("lock",)
# Fade to black over 1 minute before locking the screen
fade = 60
else:
# Settings for when the lock screen is active.
# Turn something off after 15 seconds
delay = 15
bat_status = pathlib.Path("/sys/class/power_supply/BAT0/status")
if bat_status.exists() and bat_status.read_text() == "Discharging\n" and not is_unattended:
# If running on battery, suspend the system.
action = ("power", "suspend")
else:
# Otherwise (AC power), just turn the screen(s) off.
action = ("dpms",)
# Fade to black over 5 seconds before turning off
fade = 5
# Register our selected modules at their corresponding idle times.
if c.is_idle_for(delay - fade):
c.run_module("xbacklight", "-time", str(fade * 1000), "-fps", "15")
if c.is_idle_for(delay):
c.run_module(*action)
# Register some on-lock modules, to do some more interesting things
# when the screen is locked. These will be started when the lock
# screen starts, and will be stopped when the lock screen exits.
if c.is_locked():
# Prevent TTY switching.
# No need to worry if you forgot to log out on a TTY before walking away.
c.run_module("physlock_vtswitch")
# Pause dunst notifications.
# Don't want your PMs to pop up on top of the lock screen.
c.run_module("dunst")
# Change the keyboard to US QWERTY before locking the screen.
# Avoid frustration due to your password not working when you were
# actually typing it in Cyrillic.
c.run_module("xkblayout")
# Start motion.
if is_main_user:
c.run_module("motion")
# Stop Picom.
c.run_module("compton")
# Finally, add the lock screen itself. It should be the last module
# to run, to ensure that other security modules run before the lock
# screen becomes visible, thus confirming that the machine is secure.
c.run_module(
"i3lock",
"--show-failed-attempts",
"--image",
os.path.expanduser("~/data/images/wallpaper/blurred.png"),
)
# Configure remote sessions, which synchronize multiple blankie instances.
# These modules run independently of environment conditions.
# The network key. Keep this safe!
bus_key_path = os.path.expanduser("~/.config/private/blankie-bus-key")
with open(bus_key_path, "rb") as f:
c.bus_key = f.read()
bus_addr = ('127.0.0.1', 25265) # "BLANK"
if is_main_user:
c.run_module("bus_server", bus_addr)
c.run_module("remote_sender", bus_addr)
import blankie.module
import blankie.modules.session.x11
# Custom on_lock Blankie module: motion
# Starts Motion for video surveillance while locked.
class MotionModule(blankie.module.Module):
name = "motion"
def start(self):
subprocess.check_call(["systemctl", "--user", "start", "motion.service"])
def stop(self):
subprocess.check_call(["systemctl", "--user", "stop", "motion.service"])
# Custom on_lock Blankie module: xkblayout
# I use a custom script which replaces the entire XKB configuration,
# to avoid some programs still using QWERTY keys in their hotkey bindings.
class XKBLayoutPerSessionModule(blankie.module.Module):
name = "internal-xkblayout-session"
def __init__(self, session_spec):
super().__init__()
self.display = session_spec[1]
def start(self):
subprocess.check_call(
[os.path.expanduser("~/libexec/xkblayout"), "1"], # US Dvorak
env=dict(os.environ, DISPLAY=self.display),
)
def stop(self):
pass
class XKBLayoutModule(blankie.session.PerSessionModuleLauncher):
name = "xkblayout"
per_session_name = XKBLayoutPerSessionModule.name
session_type = blankie.modules.session.x11.X11Session.name # 'session.x11'
# Custom on_lock Blankie module: compton
# Disable picom (prev. compton), as it can cause a delay in the
# lockscreen obscuring the screen.
class ComptonPerSessionModule(blankie.module.Module):
name = "internal-compton-session"
def __init__(self, session_spec):
super().__init__()
self.display = session_spec[1]
def start(self):
subprocess.check_call(
["systemctl", "--user", "stop", "cs-x-compton@" + self.display + ".service"]
)
def stop(self):
subprocess.check_call(
[
"systemctl",
"--user",
"start",
"cs-x-compton@" + self.display + ".service",
]
)
class ComptonModule(blankie.session.PerSessionModuleLauncher):
name = "compton"
per_session_name = ComptonPerSessionModule.name
session_type = blankie.modules.session.x11.X11Session.name # 'session.x11'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment