diff --git a/application.go b/application.go index 7fe44c4..811e197 100644 --- a/application.go +++ b/application.go @@ -1,5 +1,6 @@ package stone +import "image" import "image/color" // Application represents an application. @@ -7,17 +8,11 @@ type Application struct { DamageBuffer title string + icons []image.Image backend Backend config Config } -// SetTitle sets the application's title. If in a window, it will appear as the -// window's name. -func (application *Application) SetTitle (title string) { - application.title = title - application.backend.SetTitle(title) -} - // Run initializes the application, starts it, and then returns a channel that // broadcasts events. If no suitable backend can be found, an error is returned. func (application *Application) Run () ( @@ -49,6 +44,36 @@ func (application *Application) Run () ( return } +// SetTitle sets the application's title. If in a window, it will appear as the +// window's name. +func (application *Application) SetTitle (title string) (err error) { + application.title = title + if application.backend != nil { + err = application.backend.SetTitle(title) + } + + return +} + +func (application *Application) Title () (title string) { + title = application.title + return +} + +func (application *Application) SetIcon (sizes []image.Image) (err error) { + application.icons = sizes + if application.backend != nil { + err = application.backend.SetIcon(sizes) + } + + return +} + +func (application *Application) Icon () (sizes []image.Image) { + sizes = application.icons + return +} + // Config returns a pointer to the application's configuration. func (application *Application) Config () (config *Config) { config = &application.config diff --git a/assets/scaffold16.png b/assets/scaffold16.png new file mode 100644 index 0000000..6fb6890 Binary files /dev/null and b/assets/scaffold16.png differ diff --git a/assets/scaffold32.png b/assets/scaffold32.png new file mode 100644 index 0000000..abb193a Binary files /dev/null and b/assets/scaffold32.png differ diff --git a/backend.go b/backend.go index a6b5b98..c4f8278 100644 --- a/backend.go +++ b/backend.go @@ -5,8 +5,8 @@ import "errors" type Backend interface { Run (channel chan(Event)) - SetTitle (title string) - SetIcon (icons []image.Image) + SetTitle (title string) (err error) + SetIcon (icons []image.Image) (err error) } type BackendFactory func (application *Application) (backend Backend, err error) diff --git a/backends/x/x.go b/backends/x/x.go index 07f0378..606602f 100644 --- a/backends/x/x.go +++ b/backends/x/x.go @@ -7,7 +7,7 @@ import "image" import "github.com/jezek/xgb" import "github.com/jezek/xgbutil" import "github.com/jezek/xgb/xproto" -// import "github.com/jezek/xgbutil/ewmh" +import "github.com/jezek/xgbutil/ewmh" import "github.com/jezek/xgbutil/xevent" import "github.com/jezek/xgbutil/xwindow" import "github.com/jezek/xgbutil/xgraphics" @@ -68,12 +68,46 @@ func (backend *Backend) Run (channel chan(stone.Event)) { } } -func (backend *Backend) SetTitle (title string) { - +func (backend *Backend) SetTitle (title string) (err error) { + err = ewmh.WmNameSet(backend.connection, backend.window.Id, title) + return } -func (backend *Backend) SetIcon (icons []image.Image) { +func (backend *Backend) SetIcon (icons []image.Image) (err error) { + wmIcons := []ewmh.WmIcon { } + for _, icon := range icons { + width := icon.Bounds().Max.X + height := icon.Bounds().Max.Y + wmIcon := ewmh.WmIcon { + Width: uint(width), + Height: uint(height), + Data: make ([]uint, width * height), + } + + // manually convert image data beacuse of course we have to do + // this + index := 0 + for y := 0; y < height; y ++ { + for x := 0; x < width; x ++ { + r, g, b, a := icon.At(x, y).RGBA() + r >>= 8 + g >>= 8 + b >>= 8 + a >>= 8 + wmIcon.Data[index] = + (uint(a) << 24) | + (uint(r) << 16) | + (uint(g) << 8) | + (uint(b) << 0) + index ++ + }} + + wmIcons = append(wmIcons, wmIcon) + } + + err = ewmh.WmIconSet(backend.connection, backend.window.Id, wmIcons) + return } func (backend *Backend) handleXEvent (event xgb.Event) { @@ -192,6 +226,8 @@ func factory (application *stone.Application) (output stone.Backend, err error) 0) backend.window.Map() backend.window.Listen(xproto.EventMaskStructureNotify) + backend.SetTitle(application.Title()) + backend.SetIcon(application.Icon()) // create a canvas backend.canvas = xgraphics.New ( diff --git a/examples/hello/main.go b/examples/hello/main.go index 1dd1f89..38b168b 100644 --- a/examples/hello/main.go +++ b/examples/hello/main.go @@ -3,11 +3,29 @@ package main import "os" import "fmt" import "time" +import "image" +import _ "image/png" import "git.tebibyte.media/sashakoshka/stone" import _ "git.tebibyte.media/sashakoshka/stone/backends/x" func main () { application := &stone.Application { } + application.SetTitle("hellorld") + application.SetSize(12, 2) + + iconFile16, err := os.Open("assets/scaffold16.png") + if err != nil { panic(err) } + icon16, _, err := image.Decode(iconFile16) + if err != nil { panic(err) } + iconFile16.Close() + iconFile32, err := os.Open("assets/scaffold32.png") + if err != nil { panic(err) } + icon32, _, err := image.Decode(iconFile32) + if err != nil { panic(err) } + iconFile16.Close() + + application.SetIcon([]image.Image { icon16, icon32 }) + channel, err := application.Run() if err != nil { panic(err) }