Skip to content

Embed a nice screensaver so we don't depend on XScreensaver #267

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
77faf19
Add option to use FyshOS screen saver
andydotxyz Jan 21, 2025
e4e59c4
Merge from develop
andydotxyz Jan 21, 2025
15503f4
Merge branch 'develop' into feature/screensaver
andydotxyz Jan 21, 2025
3ce905a
Refactor screensaver X11 code to new file
andydotxyz Jan 25, 2025
0719c0a
Don't allow system keys when screensaver up
andydotxyz Jan 25, 2025
1c6b1d2
Latest saver library
andydotxyz Jan 25, 2025
f3484b0
Always lock
andydotxyz Jan 25, 2025
db1b915
Working CI
andydotxyz Jan 25, 2025
b124c08
Merge branch 'develop' into feature/screensaver
andydotxyz Jan 25, 2025
081b2f1
Merge branch 'develop' into feature/screensaver
andydotxyz Jan 25, 2025
2290787
Reduce cyclo
andydotxyz Jan 25, 2025
13e3be5
Fix test failure with overlay
andydotxyz Jan 25, 2025
b2d6c59
Fix header for macOS preview build
andydotxyz Jan 25, 2025
403a6b3
Fix lint errors
andydotxyz Jan 26, 2025
36b9538
Merge branch 'develop' into feature/screensaver
andydotxyz Feb 8, 2025
6bae5ff
Using Fyne develop without patches
andydotxyz Feb 8, 2025
979b078
Don't invoke screensaver automatically if inhinbited
andydotxyz Feb 11, 2025
4f215e8
Added missing generated file
andydotxyz Feb 11, 2025
e577e1a
Fix output format of generated file
andydotxyz Feb 11, 2025
65978ae
Don't confuse comment with package doc
andydotxyz Feb 11, 2025
7733c8f
Upgrade to the Fyne 2.6 beta
andydotxyz Mar 1, 2025
7e259b3
More threading changes
andydotxyz Mar 1, 2025
f0cfc33
Update more deps
andydotxyz Mar 1, 2025
ce22676
Merge branch 'develop' into feature/screensaver
andydotxyz Mar 1, 2025
6424cf1
And latest terminal
andydotxyz Mar 2, 2025
e56e82b
Fix menu layout
andydotxyz Mar 28, 2025
e60e14d
Complete upgrade to fyne 2.6.0 and innerwindow draw
andydotxyz Apr 2, 2025
997a4c6
Merge branch 'develop' into feature/screensaver
andydotxyz Apr 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/platform_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
go-version: ${{ matrix.go-version }}

- name: Get dependencies
run: sudo apt-get update && sudo apt-get install gcc libgl1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev libx11-dev xorg-dev bc
run: sudo apt-get update && sudo apt-get install gcc libgl1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev libx11-dev xorg-dev bc libpam-dev
if: ${{ runner.os == 'Linux' }}

- name: Tests
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/static_analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

- name: Get dependencies
run: |
sudo apt-get update && sudo apt-get install gcc libgl1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev libx11-dev xorg-dev
sudo apt-get update && sudo apt-get install gcc libgl1-mesa-dev libegl1-mesa-dev libgles2-mesa-dev libx11-dev xorg-dev libpam-dev
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
go install golang.org/x/lint/golint@latest
Expand Down
3 changes: 3 additions & 0 deletions desk.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ type Desktop interface {

Desktop() int
SetDesktop(int)

DelayScreenSaver()
TriggerScreenSaver()
}

var instance Desktop
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ module fyshos.com/fynedesk
go 1.19

require (
fyne.io/fyne/v2 v2.5.5-0.20250208132135-967702162d53
fyne.io/fyne/v2 v2.5.5-0.20250208220124-36dce94b9595
github.com/BurntSushi/xgb v0.0.0-20201008132610-5f9e7b3c49cd
github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e
github.com/FyshOS/appie v0.0.0-20250103211310-00f097d8e19d
github.com/FyshOS/backgrounds v0.0.0-20230616202904-0a8b6ebaa184
github.com/FyshOS/saver v0.0.0-20250125211336-528339462781
github.com/Knetic/govaluate v3.0.0+incompatible
github.com/disintegration/imaging v1.6.2
github.com/godbus/dbus/v5 v5.1.0
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
fyne.io/fyne/v2 v2.5.5-0.20250208132135-967702162d53 h1:qXq2uL+bCtlg9uNnlXGdj+9eamAjMhuL4fQVDJrHVqo=
fyne.io/fyne/v2 v2.5.5-0.20250208132135-967702162d53/go.mod h1:6/uEYg4FEhspAcWgsokutm9wFMHDNSYuEHCKTYWSho8=
fyne.io/fyne/v2 v2.5.5-0.20250208220124-36dce94b9595 h1:oWbNIUNmmRx3DjnGQ5lKzKGvmEemtxcSrcAZKvSY/IE=
fyne.io/fyne/v2 v2.5.5-0.20250208220124-36dce94b9595/go.mod h1:6/uEYg4FEhspAcWgsokutm9wFMHDNSYuEHCKTYWSho8=
fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg=
fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
github.com/ActiveState/termtest/conpty v0.5.0 h1:JLUe6YDs4Jw4xNPCU+8VwTpniYOGeKzQg4SM2YHQNA8=
Expand All @@ -59,6 +59,8 @@ github.com/FyshOS/appie v0.0.0-20250103211310-00f097d8e19d h1:bkIQPpxGMalOufoLbL
github.com/FyshOS/appie v0.0.0-20250103211310-00f097d8e19d/go.mod h1:Gtvb1fKDXbE9HjMtoYdB2MPSSGy6PdtMl0TC9dSF8q0=
github.com/FyshOS/backgrounds v0.0.0-20230616202904-0a8b6ebaa184 h1:Za0NHFsT0CCXf/X4hEaywjvEECccrM/xVVL8BzAy6JI=
github.com/FyshOS/backgrounds v0.0.0-20230616202904-0a8b6ebaa184/go.mod h1:cOUmJ3HUVmH3W3u9Gj5hM73ZgrDxGNHKMr5T/sBKqLU=
github.com/FyshOS/saver v0.0.0-20250125211336-528339462781 h1:jGmHNeimIf4DDEe8jkoUNX9r10+qGtkUG+3PMpjGSEs=
github.com/FyshOS/saver v0.0.0-20250125211336-528339462781/go.mod h1:yIuAuYqnEyKaiNU4MD4xmyLcZl9QdDr2uTmT7lt02tI=
github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
Expand Down
61 changes: 31 additions & 30 deletions internal/ui/desk.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,12 @@ func (l *desktop) ShowMenuAt(menu *fyne.Menu, pos fyne.Position) {
}

func (l *desktop) updateBackgrounds(path string) {
l.root.Content().(*fyne.Container).Objects[0].(*background).updateBackground(path)
root := l.root.Content().(*fyne.Container).Objects[0]
if back, ok := root.(*background); ok {
back.updateBackground(path)
} else { // embed mode has another container
root.(*fyne.Container).Objects[0].(*background).updateBackground(path)
}
}

func (l *desktop) createPrimaryContent() fyne.CanvasObject {
Expand Down Expand Up @@ -150,6 +155,7 @@ func (l *desktop) RecentApps() []appie.AppData {

func (l *desktop) Run() {
go l.wm.Run()
go l.watchScreenActivity()
l.run() // use the configured run method
}

Expand Down Expand Up @@ -343,19 +349,9 @@ func (l *desktop) registerShortcuts() {
l.AddShortcut(fynedesk.NewShortcut("Calculator", fynedesk.KeyCalculator, 0),
l.calculator)
l.AddShortcut(fynedesk.NewShortcut("Lock screen", fyne.KeyL, fynedesk.UserModifier),
l.lockScreen)
}

func (l *desktop) startXscreensaver() {
_, err := exec.LookPath("xscreensaver")
if err != nil {
fyne.LogError("xscreensaver command not found", err)
return
}
err = exec.Command("xscreensaver", "-no-splash").Start()
if err != nil {
fyne.LogError("Failed to lock screen", err)
}
func() {
l.TriggerScreenSaver()
})
}

// Screens returns the screens provider of the current desktop environment for access to screen functionality.
Expand All @@ -374,7 +370,9 @@ func NewDesktop(app fyne.App, mgr fynedesk.WindowManager, icons appie.Provider,

desk.setupRoot()
wm.StartAuthAgent()
go desk.startXscreensaver()
if desk.Settings().ScreenSaverType() == "XScreensaver" {
go desk.startXscreensaver()
}
return desk
}

Expand All @@ -383,12 +381,14 @@ func NewDesktop(app fyne.App, mgr fynedesk.WindowManager, icons appie.Provider,
// If run during CI for testing it will return an in-memory window using the
// fyne/test package.
func NewEmbeddedDesktop(app fyne.App, icons appie.Provider) fynedesk.Desktop {
desk := newDesktop(app, &embededWM{}, icons)
wm := &embededWM{}
desk := newDesktop(app, wm, icons)
desk.run = desk.runEmbed
desk.showMenu = desk.showMenuEmbed

desk.root = desk.newDesktopWindowEmbed()
desk.root.SetContent(desk.createPrimaryContent())
over := wm.setWindow(desk.root)
desk.root.SetContent(container.NewStack(desk.createPrimaryContent(), over))
return desk
}

Expand All @@ -411,16 +411,17 @@ func (l *desktop) calculator() {
}
}

func (l *desktop) lockScreen() {
_, err := exec.LookPath("xscreensaver-command")
if err != nil {
fyne.LogError("xscreensaver-command not found", err)
l.WindowManager().Blank()
return
}
err = exec.Command("xscreensaver-command", "-lock").Start()
if err != nil {
fyne.LogError("Failed to lock screen", err)
l.WindowManager().Blank()
}
}
//func (l *desktop) runCommand() {
// w := l.app.NewWindow("Run Command")
// input := widget.NewEntry()
// // TODO add history etc...
// run := widget.NewButton("Run", func() {
//
// })
// run.Importance = widget.HighImportance
//
// w.SetContent(container.NewVBox(widget.NewLabel("Enter command to run:"),
// container.NewBorder(nil, nil, nil, run, input)))
// w.Resize(fyne.NewSize(250, 40))
// w.Show()
//}
2 changes: 1 addition & 1 deletion internal/ui/desk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestBackgroundChange(t *testing.T) {
l.settings = wmTest.NewSettings()
l.setupRoot()

bg := l.root.Content().(*fyne.Container).Objects[0].(*background)
bg := l.root.Content().(*fyne.Container).Objects[0].(*fyne.Container).Objects[0].(*background)

workingDir, err := os.Getwd()
if err != nil {
Expand Down
63 changes: 61 additions & 2 deletions internal/ui/embed_wm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ package ui

import (
"image"

"fyne.io/fyne/v2"
"image/color"

"fyshos.com/fynedesk"
"github.com/FyshOS/saver"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
deskDriver "fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/widget"
)

type embededWM struct {
windows []fynedesk.Window
root fyne.Window
}

func (e *embededWM) AddWindow(win fynedesk.Window) {
Expand Down Expand Up @@ -79,3 +86,55 @@ func (e *embededWM) Close() {
windows[0].Close() // ensure our root is asked to close as well
}
}

var visible bool

func (e *embededWM) ShowScreensaver(s *saver.ScreenSaver) {
if visible {
return
}

visible = true
over := container.NewStack(canvas.NewRectangle(color.Black))

s.OnUnlocked = func() {
visible = false
e.root.Canvas().Overlays().Remove(over)
}

over.Add(s.MakeUI(e.root))
over.Resize(e.root.Canvas().Size())
e.root.Canvas().Overlays().Add(over)
}

func (e *embededWM) setWindow(win fyne.Window) fyne.CanvasObject {
e.root = win

return newSaverMonitor(fynedesk.Instance().DelayScreenSaver)
}

type saverMonitor struct {
widget.BaseWidget

cb func()
}

func newSaverMonitor(cb func()) fyne.CanvasObject {
s := &saverMonitor{cb: cb}
s.ExtendBaseWidget(s)
return s
}

func (s *saverMonitor) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(canvas.NewRectangle(color.Transparent))
}

func (s *saverMonitor) MouseIn(*deskDriver.MouseEvent) {
}

func (s *saverMonitor) MouseMoved(*deskDriver.MouseEvent) {
s.cb()
}

func (s *saverMonitor) MouseOut() {
}
11 changes: 7 additions & 4 deletions internal/ui/menu.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,14 @@ func (w *widgetPanel) showAccountMenu(_ fyne.CanvasObject) {
w2.Close()
}}}
isEmbed := w.desk.(*desktop).root.Title() != RootWindowName
items1 = append(items1, &widget.Button{Icon: wmtheme.LockIcon, Importance: widget.LowImportance, OnTapped: func() {
w2.Close()
go func() {
time.Sleep(time.Millisecond * 300)
w.desk.TriggerScreenSaver()
}()
}})
if !isEmbed {
items1 = append(items1, &widget.Button{Icon: wmtheme.LockIcon, Importance: widget.LowImportance, OnTapped: func() {
w2.Close()
w.desk.(*desktop).lockScreen()
}})
if os.Getenv("FYNE_DESK_RUNNER") != "" {
items1 = append(items1, &widget.Button{Icon: theme.ViewRefreshIcon(), Importance: widget.LowImportance, OnTapped: func() {
os.Exit(5)
Expand Down
59 changes: 59 additions & 0 deletions internal/ui/screensaver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package ui

import (
"os/exec"
"time"

"github.com/FyshOS/saver"

"fyne.io/fyne/v2"
)

func (l *desktop) startXscreensaver() {
_, err := exec.LookPath("xscreensaver")
if err != nil {
fyne.LogError("xscreensaver command not found", err)
return
}
err = exec.Command("xscreensaver", "-no-splash").Start()
if err != nil {
fyne.LogError("Failed to lock screen", err)
}
}

func (l *desktop) TriggerScreenSaver() {
s := saver.NewScreenSaver(nil)
s.ClockFormat = l.settings.ClockFormatting()
if l.settings.ScreenSaverClock() {
s.Label = "(clock)"
} else {
s.Label = l.settings.ScreenSaverLabel()
}
s.Lock = true

go l.wm.ShowScreensaver(s)
}

var lastActivity time.Time

func (l *desktop) DelayScreenSaver() {
lastActivity = time.Now()
}

func (l *desktop) watchScreenActivity() {
idle := false
to := time.NewTicker(5 * time.Second)

for range to.C {
if lastActivity.Add(time.Minute * 5).Before(time.Now()) {

if !idle {
idle = true

l.TriggerScreenSaver()
}
} else {
idle = false
}
}
}
Loading