Skip to content

Commit

Permalink
Merge pull request #256 from andydotxyz/feature/quaketerm
Browse files Browse the repository at this point in the history
Add quake mode terminal module
  • Loading branch information
andydotxyz committed Feb 21, 2024
2 parents 336fa58 + 4cb19e0 commit 632a47c
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 8 deletions.
1 change: 1 addition & 0 deletions cmd/fynedesk/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
_ "fyshos.com/fynedesk/modules/composit"
_ "fyshos.com/fynedesk/modules/desktops"
_ "fyshos.com/fynedesk/modules/launcher"
_ "fyshos.com/fynedesk/modules/quaketerm"
_ "fyshos.com/fynedesk/modules/status"
_ "fyshos.com/fynedesk/modules/systray"

Expand Down
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,23 @@ require (

require (
fyne.io/systray v1.10.1-0.20231230205326-d160fd363db9 // indirect
github.com/ActiveState/termtest/conpty v0.5.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 // indirect
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966 // indirect
github.com/creack/pty v1.1.11 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fredbi/uri v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect
github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a // indirect
github.com/fyne-io/terminal v0.0.0-20240206170039-2e129cdfd85f
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20231223183121-56fa3ac82ce7 // indirect
github.com/go-text/render v0.0.0-20230619120952-35bccb6164b8 // indirect
github.com/go-text/typesetting v0.1.0 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
Expand All @@ -44,7 +47,6 @@ require (
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect
)
Expand Down
11 changes: 9 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ fyne.io/fyne/v2 v2.4.4 h1:4efSRpoikcGbqQN83yzC9WmF8UNq9olsaJQ/Ejme6Z8=
fyne.io/fyne/v2 v2.4.4/go.mod h1:VyrxAOZ3NRZRWBvNIJbfqoKOG4DdbewoPk7ozqJKNPY=
fyne.io/systray v1.10.1-0.20231230205326-d160fd363db9 h1:E/gHmMVyk8TuI6JIgNIv/Qu1JABMVFBIkQ8lYRa5gkQ=
fyne.io/systray v1.10.1-0.20231230205326-d160fd363db9/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
github.com/ActiveState/termtest/conpty v0.5.0 h1:JLUe6YDs4Jw4xNPCU+8VwTpniYOGeKzQg4SM2YHQNA8=
github.com/ActiveState/termtest/conpty v0.5.0/go.mod h1:LO4208FLsxw6DcNZ1UtuGUMW+ga9PFtX4ntv8Ymg9og=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 h1:1qlsVAQJXZHsaM8b6OLVo6muQUQd4CwkH/D3fnnbHXA=
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966 h1:lTG4HQym5oPKjL7nGs+csTgiDna685ZXjxijkne828g=
Expand Down Expand Up @@ -70,6 +74,8 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
Expand All @@ -96,6 +102,8 @@ github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a h1:ybgRdYvAHTn93HW
github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a/go.mod h1:gsGA2dotD4v0SR6PmPCYvS9JuOeMwAtmfvDE7mbYXMY=
github.com/fyne-io/image v0.0.0-20221020213044-f609c6a24345 h1:ONkcbJmsWUOHyjUm0wlnkFc/uaacFFtStVbsG6qJfew=
github.com/fyne-io/image v0.0.0-20221020213044-f609c6a24345/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0=
github.com/fyne-io/terminal v0.0.0-20240206170039-2e129cdfd85f h1:i+TynW/8eeknoct3S234fwOLIwobeD2ujxVo3jgpIjA=
github.com/fyne-io/terminal v0.0.0-20240206170039-2e129cdfd85f/go.mod h1:H0b/BtaKEdivaCBKKPIiTEVPt9yG7rLJCj2AR49hi8M=
github.com/fyne-io/xgbutil v0.0.0-20191220152344-7d838166824d h1:8+poQtDqiRfAZmeyYRlInuaIBsQEflmxtpJeZklvNuE=
github.com/fyne-io/xgbutil v0.0.0-20191220152344-7d838166824d/go.mod h1:vPqYMuTmTyrLNDQWQXy9lqdnV+WRQn6jhaSon8TppBs=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
Expand Down Expand Up @@ -245,7 +253,6 @@ github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down Expand Up @@ -447,6 +454,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200428200454-593003d681fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down Expand Up @@ -647,7 +655,6 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Expand Down
5 changes: 5 additions & 0 deletions internal/ui/desk.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ func (l *desktop) SetDesktop(id int) {

fyne.NewAnimation(canvas.DurationStandard, func(f float32) {
for i, item := range l.wm.Windows() {
// TODO move this to floating once we support them
if item.Properties().SkipTaskbar() {
continue
}

newX := starts[i].X + deltas[i].DX*f
newY := starts[i].Y + deltas[i].DY*f

Expand Down
15 changes: 15 additions & 0 deletions internal/x11/win/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ func (c *client) Maximized() bool {
}

func (c *client) Move(pos fyne.Position) {
if c.frame == nil {
return
}
screen := fynedesk.Instance().Screens().ScreenForWindow(c)

targetX := int16(pos.X * screen.CanvasScale())
Expand Down Expand Up @@ -317,7 +320,19 @@ func (c *client) Position() fyne.Position {
float32(c.frame.y)/screen.CanvasScale())
}

func (c *client) Resize(s fyne.Size) {
if c.frame == nil {
return
}
screen := fynedesk.Instance().Screens().ScreenForWindow(c)

c.frame.updateGeometry(c.frame.x, c.frame.y, uint16(s.Width*screen.Scale), uint16(s.Height*screen.Scale), false)
}

func (c *client) Size() fyne.Size {
if c.frame == nil {
return fyne.Size{}
}
screen := fynedesk.Instance().Screens().ScreenForWindow(c)

return fyne.NewSize(
Expand Down
7 changes: 5 additions & 2 deletions internal/x11/wm/desk.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const (
keyCodeEscape = 9
keyCodeTab = 23
keyCodeReturn = 36
keyCodeBacktick = 49
keyCodeAlt = 64
keyCodeSpace = 65
keyCodePrintScreen = 107
Expand Down Expand Up @@ -339,10 +340,12 @@ func (x *x11WM) keyNameToCode(n fyne.KeyName) xproto.Keycode {
return keyCodeUp
case fyne.KeyDown:
return keyCodeDown
case deskDriver.KeyPrintScreen:
return keyCodePrintScreen
case fyne.KeyTab:
return keyCodeTab
case fyne.KeyBackTick:
return keyCodeBacktick
case deskDriver.KeyPrintScreen:
return keyCodePrintScreen
case fynedesk.KeyBrightnessDown:
return keyCodeBrightLess
case fynedesk.KeyBrightnessUp:
Expand Down
2 changes: 1 addition & 1 deletion modules/desktops/pager.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (p *pager) refreshFrom(oldID int) {

for j := len(wins) - 1; j >= 0; j-- {
win := wins[j]
if win.Iconic() {
if win.Iconic() || win.Properties().SkipTaskbar() {
continue
}

Expand Down
7 changes: 7 additions & 0 deletions modules/quaketerm/init.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package launcher

import "fyshos.com/fynedesk"

func init() {
fynedesk.RegisterModule(termMeta)
}
167 changes: 167 additions & 0 deletions modules/quaketerm/term.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package launcher

import (
"time"

"fyshos.com/fynedesk"
"fyshos.com/fynedesk/internal/ui"
wmTheme "fyshos.com/fynedesk/theme"
"github.com/fyne-io/terminal"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/theme"
)

const (
delay = time.Second / 25
termTitle = "Quake Terminal " + ui.SkipTaskbarHint
height = 240
step = 40
)

var termMeta = fynedesk.ModuleMetadata{
Name: "\"Quake\" (hover) terminal",
NewInstance: newTerm,
}

type term struct {
shown bool
win fynedesk.Window
ui fyne.Window
}

func (t *term) Destroy() {
}

func (t *term) Metadata() fynedesk.ModuleMetadata {
return termMeta
}

func (t *term) Shortcuts() map[*fynedesk.Shortcut]func() {
return map[*fynedesk.Shortcut]func(){
&fynedesk.Shortcut{Name: "Open Quake Terminal", KeyName: fyne.KeyBackTick, Modifier: fynedesk.UserModifier}: func() {
t.toggle()
}}
}

func (t *term) createTerm() {
win := fyne.CurrentApp().Driver().(desktop.Driver).CreateSplashWindow()
win.SetTitle(termTitle)

bg := canvas.NewRectangle(theme.BackgroundColor())
img := canvas.NewImageFromResource(theme.NewDisabledResource(theme.ComputerIcon()))
img.FillMode = canvas.ImageFillContain
img.SetMinSize(fyne.NewSize(200, 200))
over := canvas.NewRectangle(wmTheme.WidgetPanelBackground())
matchTheme(bg, over)

console := terminal.New()
win.SetContent(container.NewStack(bg, img, over, console))
win.Canvas().Focus(console)
t.ui = win

go func() {
err := console.RunLocalShell()
if err != nil {
fyne.LogError("Failed to open terminal", err)
}
t.hide() // terminal exited

t.createTerm() // reset for next usage
}()
}

func (t *term) getHandle() fynedesk.Window {
// TODO a better way to capture window frame without showing it and waiting...
//t.ui.Resize(fyne.NewSize(0, 0))
t.ui.Show()

i := 0
for {
time.Sleep(time.Second / 50)

for _, w := range fynedesk.Instance().WindowManager().Windows() {
if w.Properties().Title() == termTitle {
return w
}
}

i++
if i > 50 {
return nil // something went wrong
}
}
}

func (t *term) hide() {
screen := fynedesk.Instance().Screens().Primary()
left := float32(screen.X) / screen.Scale
y := float32(screen.Y) / screen.Scale
end := float32(screen.Y)/screen.Scale - height
for y > end {
t.win.Move(fyne.NewPos(left, y))
time.Sleep(delay)
y -= step
}
t.win.Move(fyne.NewPos(left, end))

t.ui.Hide()
t.shown = false
}

func (t *term) show() {
screen := fynedesk.Instance().Screens().Primary()
t.win.Resize(fyne.NewSize(float32(screen.Width)/screen.Scale, height))
// t.ui.Show()
t.win.RaiseToTop()

left := float32(screen.X) / screen.Scale
y := float32(screen.Y)/screen.Scale - height
end := float32(screen.Y) / screen.Scale
for y < end {
t.win.Resize(fyne.NewSize(float32(screen.Width)/screen.Scale, height)) // force it ASAP
t.win.Move(fyne.NewPos(left, y))
time.Sleep(delay)
y += step
}
t.win.Move(fyne.NewPos(left, end))
t.shown = true
}

func (t *term) toggle() {
if t.ui == nil {
t.createTerm() // lazy load UI
}

if !t.shown {
t.win = t.getHandle()

t.show()
} else {
t.hide()
t.win = nil
}
}

func matchTheme(bg, over *canvas.Rectangle) {
ch := make(chan fyne.Settings)
go func() {
for {
<-ch

bg.FillColor = theme.BackgroundColor()
bg.Refresh()
over.FillColor = wmTheme.WidgetPanelBackground()
over.Refresh()
}
}()
fyne.CurrentApp().Settings().AddChangeListener(ch)
}

func newTerm() fynedesk.Module {
// don't load UI until it is first called on
return &term{}
}
5 changes: 4 additions & 1 deletion test/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (w *Window) Maximized() bool {
}

// Move the window, does nothing in test windows
func (w *Window) Move(fyne.Position) {}
func (w *Window) Move(_ fyne.Position) {}

// Parent returns a window that this should be positioned within, if set.
func (w *Window) Parent() fynedesk.Window {
Expand All @@ -94,6 +94,9 @@ func (w *Window) Position() fyne.Position {
return fyne.NewPos(0, 0)
}

// Resize the window, does nothing in test windows
func (w *Window) Resize(_ fyne.Size) {}

// Size returns 0x0 for test windows
func (w *Window) Size() fyne.Size { return fyne.Size{} }

Expand Down
1 change: 1 addition & 0 deletions window.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type Window interface {
Position() fyne.Position
Size() fyne.Size
Move(position fyne.Position)
Resize(fyne.Size)

Desktop() int
SetDesktop(int)
Expand Down

0 comments on commit 632a47c

Please sign in to comment.