~whynothugo/systemd-lock-handler

68d18ad889e75f063b47caf46309650436f0a04b — Hugo Osvaldo Barrera 3 years ago f9e5a8c
Notify systemd when we've initialised successfully
2 files changed, 55 insertions(+), 36 deletions(-)

M main.go
M systemd-lock-handler.service
M main.go => main.go +54 -36
@@ 1,13 1,14 @@
package main

import (
	"fmt"
	"context"
	"fmt"
	"log"
	"os/user"

	"github.com/godbus/dbus/v5"
	"github.com/coreos/go-systemd/v22/daemon"
	systemd "github.com/coreos/go-systemd/v22/dbus"
	"github.com/godbus/dbus/v5"
)

func StartSystemdUserUnit(unitName string) error {


@@ 30,7 31,6 @@ func ListenForSleep() {
	if err != nil {
		log.Fatalln("Could not connect to the system D-Bus", err)
	}
	defer conn.Close()

	err = conn.AddMatchSignal(
		dbus.WithMatchObjectPath("/org/freedesktop/login1"),


@@ 42,16 42,21 @@ func ListenForSleep() {
	}

	c := make(chan *dbus.Signal, 10)
	conn.Signal(c)
	for {
		<-c
		log.Println("The system is going to sleep")

		err = StartSystemdUserUnit("sleep.target")
		if err != nil {
			log.Println("Error starting sleep.target:", err)
	go func() {
		for {
			<-c
			log.Println("The system is going to sleep")

			err = StartSystemdUserUnit("sleep.target")
			if err != nil {
				log.Println("Error starting sleep.target:", err)
			}
		}
	}
	}()

	conn.Signal(c)
	log.Println("Listening for sleep events...")
}

func ListenForLock(user *user.User) {


@@ 59,7 64,6 @@ func ListenForLock(user *user.User) {
	if err != nil {
		log.Fatalln("Could not connect to the system D-Bus", err)
	}
	defer conn.Close()

	err = conn.AddMatchSignal(
		dbus.WithMatchInterface("org.freedesktop.login1.Session"),


@@ 71,30 75,34 @@ func ListenForLock(user *user.User) {
	}

	c := make(chan *dbus.Signal, 10)
	conn.Signal(c)
	for {
		v := <-c

		// Get the locked session...
		obj := conn.Object("org.freedesktop.login1", v.Path)

		name, err := obj.GetProperty("org.freedesktop.login1.Session.Name")
		if err != nil {
			log.Println("WARNING: Could not obtain details for locked session:", err)
			continue
		}

		// ... And check that it belongs to the current user:
		if name.Value() != user.Username {
			continue
	go func() {
		for {
			v := <-c

			// Get the locked session...
			obj := conn.Object("org.freedesktop.login1", v.Path)

			name, err := obj.GetProperty("org.freedesktop.login1.Session.Name")
			if err != nil {
				log.Println("WARNING: Could not obtain details for locked session:", err)
				continue
			}

			// ... And check that it belongs to the current user:
			if name.Value() != user.Username {
				continue
			}
			log.Println("Session locked for current user.")

			err = StartSystemdUserUnit("lock.target")
			if err != nil {
				log.Println("Error starting lock.target:", err)
			}
		}
		log.Println("Session locked for current user.")
	}()

		err = StartSystemdUserUnit("lock.target")
		if err != nil {
			log.Println("Error starting lock.target:", err)
		}
	}
	conn.Signal(c)
	log.Println("Listening for lock events...")
}

func main() {


@@ 106,8 114,18 @@ func main() {
	}
	log.Println("Running for user:", user.Username)

	go ListenForSleep()
	go ListenForLock(user)
	ListenForSleep()
	ListenForLock(user)

	log.Println("Initialization complete.")

	sent, err := daemon.SdNotify(true, daemon.SdNotifyReady)
	if !sent {
		log.Println("Couldn't call sd_notify. Not running via systemd?")
	}
	if err != nil {
		log.Println("Call to sd_notify failed:", err)
	}

	select {}
}

M systemd-lock-handler.service => systemd-lock-handler.service +1 -0
@@ 4,6 4,7 @@ Documentation=https://sr.ht/~whynothugo/systemd-lock-handler

[Service]
ExecStart=/usr/lib/systemd-lock-handler
Type=notify

[Install]
WantedBy=default.target