Invert display and lockscreen control dependencies
This commit is contained in:
parent
e6458aba0b
commit
ebbd1974df
@ -1,9 +1,6 @@
|
||||
package afterlock
|
||||
|
||||
import(
|
||||
"after-lock/evdev"
|
||||
"after-lock/lockscreen"
|
||||
"after-lock/display"
|
||||
"after-lock/atomicflag"
|
||||
"time"
|
||||
"sync"
|
||||
@ -11,6 +8,22 @@ import(
|
||||
)
|
||||
|
||||
|
||||
// Display controls and monitors the physical display
|
||||
type Display interface {
|
||||
Suspend() error
|
||||
IsOn() (bool, error)
|
||||
}
|
||||
|
||||
// Lockscreen can determine whether the screensaver is active or not
|
||||
type Lockscreen interface {
|
||||
IsActive() (bool, error)
|
||||
}
|
||||
|
||||
// KeypressDetector can wait for keypresses
|
||||
type KeypressDetector interface {
|
||||
BlockUntilKeypress(string) error
|
||||
}
|
||||
|
||||
// AfterLock suspends the display when the lockscreen is active
|
||||
type AfterLock struct {
|
||||
InitialDelay uint
|
||||
@ -19,6 +32,9 @@ type AfterLock struct {
|
||||
wg sync.WaitGroup
|
||||
stopFlag *atomicflag.AtomicFlag
|
||||
keypressFlag *atomicflag.AtomicFlag
|
||||
Display Display
|
||||
LockScreen Lockscreen
|
||||
KeypressDetector KeypressDetector
|
||||
}
|
||||
|
||||
// New constructs a new AfterLock instance
|
||||
@ -30,11 +46,12 @@ func New(keyboardDeviceNode string) *AfterLock {
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts monitoring the lockscreen/keyboard status to determine
|
||||
// Start starts monitoring the lockscreen/keyboard to determine
|
||||
// when to suspend the display.
|
||||
// Exits after the computer is unlocked
|
||||
// Requires InitialDelay, LoopDelay, Display and LockScreen to be set
|
||||
func (af *AfterLock) Start() {
|
||||
af.checkDelaysConfigured()
|
||||
af.checkStructConfigured()
|
||||
|
||||
af.wg.Add(1)
|
||||
go af.detectKeypresses()
|
||||
@ -43,18 +60,27 @@ func (af *AfterLock) Start() {
|
||||
af.hybernateDisplayLoop()
|
||||
}
|
||||
|
||||
func (af *AfterLock) checkDelaysConfigured() {
|
||||
func (af *AfterLock) checkStructConfigured() {
|
||||
if af.InitialDelay == 0 {
|
||||
panic(errors.New("InitialDelay not configured"))
|
||||
}
|
||||
if af.LoopDelay == 0 {
|
||||
panic(errors.New("LoopDelay not configured"))
|
||||
}
|
||||
if af.Display == nil {
|
||||
panic(errors.New("Display not configured"))
|
||||
}
|
||||
if af.LockScreen == nil {
|
||||
panic(errors.New("LockScreen not configured"))
|
||||
}
|
||||
if af.KeypressDetector == nil {
|
||||
panic(errors.New("KeypressDetector not configured"))
|
||||
}
|
||||
}
|
||||
|
||||
func (af *AfterLock) detectKeypresses() {
|
||||
for {
|
||||
err := evdev.BlockUntilKeypress(af.keyboardDeviceNode)
|
||||
err := af.KeypressDetector.BlockUntilKeypress(af.keyboardDeviceNode)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -68,7 +94,7 @@ func (af *AfterLock) detectKeypresses() {
|
||||
|
||||
func (af *AfterLock) hybernateDisplayLoop() {
|
||||
for {
|
||||
screenLocked, err := lockscreen.IsActive()
|
||||
screenLocked, err := af.LockScreen.IsActive()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -78,12 +104,12 @@ func (af *AfterLock) hybernateDisplayLoop() {
|
||||
return
|
||||
}
|
||||
|
||||
displayOn, err := display.IsOn()
|
||||
displayOn, err := af.Display.IsOn()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if displayOn {
|
||||
err := display.Suspend()
|
||||
err := af.Display.Suspend()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -2,10 +2,13 @@ package main
|
||||
|
||||
import (
|
||||
"after-lock/afterlock"
|
||||
"after-lock/display"
|
||||
"after-lock/keypressdetector"
|
||||
"after-lock/lockfile"
|
||||
"after-lock/lockscreen"
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -26,6 +29,9 @@ func main() {
|
||||
al := afterlock.New(keyboardDeviceNode)
|
||||
al.InitialDelay = initialDelay
|
||||
al.LoopDelay = loopDelay
|
||||
al.Display = display.Xset{}
|
||||
al.LockScreen = lockscreen.XDG{}
|
||||
al.KeypressDetector = keypressdetector.Evdev{}
|
||||
|
||||
al.Start()
|
||||
}
|
||||
|
@ -7,8 +7,11 @@ import (
|
||||
)
|
||||
|
||||
|
||||
// Suspend the display using xset
|
||||
func Suspend() error {
|
||||
// Xset monitors/controls the display using xset
|
||||
type Xset struct {}
|
||||
|
||||
// Suspend the display
|
||||
func (Xset) Suspend() error {
|
||||
cmd := exec.Command("xset",
|
||||
"dpms",
|
||||
"force",
|
||||
@ -18,7 +21,7 @@ func Suspend() error {
|
||||
}
|
||||
|
||||
// IsOn determines if the display is on
|
||||
func IsOn() (bool, error) {
|
||||
func (Xset) IsOn() (bool, error) {
|
||||
cmd := exec.Command("xset", "q")
|
||||
outputBytes, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package evdev
|
||||
package keypressdetector
|
||||
|
||||
// #cgo CFLAGS: -g -Wall
|
||||
// #include "evdev.h"
|
||||
@ -11,7 +11,11 @@ import (
|
||||
)
|
||||
|
||||
|
||||
func BlockUntilKeypress(devicePath string) error {
|
||||
// Evdev can detect keypresses on /dev/input devices
|
||||
type Evdev struct {}
|
||||
|
||||
// BlockUntilKeypress waits until a key is pressed on the specified device
|
||||
func (Evdev) BlockUntilKeypress(devicePath string) error {
|
||||
path := C.CString(devicePath)
|
||||
defer C.free(unsafe.Pointer(path))
|
||||
|
@ -6,8 +6,11 @@ import (
|
||||
)
|
||||
|
||||
|
||||
// XDG uses qdbus to monitor the freedesktop screensaver status
|
||||
type XDG struct {}
|
||||
|
||||
// IsActive checks whether the screen is locked (checks if the screensaver is active)
|
||||
func IsActive() (bool, error) {
|
||||
func (XDG) IsActive() (bool, error) {
|
||||
cmd := exec.Command("qdbus",
|
||||
"org.kde.screensaver",
|
||||
"/ScreenSaver",
|
||||
|
Loading…
Reference in New Issue
Block a user