Added untested support for OverrideRedirect windows

This commit is contained in:
Sasha Koshka 2023-04-10 16:22:47 -04:00
parent aed448671b
commit da47026d1c
2 changed files with 55 additions and 7 deletions

View File

@ -16,6 +16,7 @@ import "git.tebibyte.media/sashakoshka/tomo/canvas"
// import "runtime/debug"
type mainWindow struct { *window }
type menuWindow struct { *window }
type window struct {
backend *Backend
xWindow *xwindow.Window
@ -48,13 +49,14 @@ func (backend *Backend) NewWindow (
err error,
) {
if backend == nil { panic("nil backend") }
window, err := backend.newWindow(bounds)
window, err := backend.newWindow(bounds, false)
output = mainWindow { window }
return output, err
}
func (backend *Backend) newWindow (
bounds image.Rectangle,
bounds image.Rectangle,
override bool,
) (
output *window,
err error,
@ -66,10 +68,19 @@ func (backend *Backend) newWindow (
window.xWindow, err = xwindow.Generate(backend.connection)
if err != nil { return }
err = window.xWindow.CreateChecked (
backend.connection.RootWin(),
bounds.Min.X, bounds.Min.Y, bounds.Dx(), bounds.Dy(), 0)
if override {
err = window.xWindow.CreateChecked (
backend.connection.RootWin(),
bounds.Min.X, bounds.Min.Y, bounds.Dx(), bounds.Dy(),
xproto.CwOverrideRedirect, 1)
} else {
err = window.xWindow.CreateChecked (
backend.connection.RootWin(),
bounds.Min.X, bounds.Min.Y, bounds.Dx(), bounds.Dy(), 0)
}
if err != nil { return }
err = window.xWindow.Listen (
xproto.EventMaskExposure,
xproto.EventMaskStructureNotify,
@ -252,7 +263,8 @@ func (window *window) SetIcon (sizes []image.Image) {
}
func (window *window) NewModal (bounds image.Rectangle) (tomo.Window, error) {
modal, err := window.backend.newWindow(bounds.Add(window.metrics.bounds.Min))
modal, err := window.backend.newWindow (
bounds.Add(window.metrics.bounds.Min), false)
icccm.WmTransientForSet (
window.backend.connection,
modal.xWindow.Id,
@ -267,8 +279,24 @@ func (window *window) NewModal (bounds image.Rectangle) (tomo.Window, error) {
return modal, err
}
func (window *window) NewMenu (bounds image.Rectangle) (tomo.MenuWindow, error) {
menu, err := window.backend.newWindow (
bounds.Add(window.metrics.bounds.Min), true)
icccm.WmTransientForSet (
window.backend.connection,
menu.xWindow.Id,
window.xWindow.Id)
ewmh.WmStateSet (
window.backend.connection,
menu.xWindow.Id,
[]string { "_NET_WM_STATE_SKIP_TASKBAR" })
menu.inheritProperties(window)
return menuWindow { window: menu }, err
}
func (window mainWindow) NewPanel (bounds image.Rectangle) (tomo.Window, error) {
panel, err := window.backend.newWindow(bounds.Add(window.metrics.bounds.Min))
panel, err := window.backend.newWindow (
bounds.Add(window.metrics.bounds.Min), false)
if err != nil { return nil, err }
panel.setClientLeader(window.window)
window.setClientLeader(window.window)
@ -281,6 +309,10 @@ func (window mainWindow) NewPanel (bounds image.Rectangle) (tomo.Window, error)
return panel, err
}
func (window menuWindow) Pin () {
// TODO
}
func (window *window) inheritProperties (parent *window) {
window.SetApplicationName(parent.application)
}

View File

@ -39,6 +39,13 @@ type Window interface {
// operating system.
NewModal (bounds image.Rectangle) (Window, error)
// NewMenu creates a new temporary window for things like dropdown or
// context menus. It automatically closes when the user presses escape
// or clicks outside of it. Like NewModal, the pulldown window will
// inherit this window's application name and icon, and will be
// positioned relative to it.
NewMenu (bounds image.Rectangle) (MenuWindow, error)
// Copy puts data into the clipboard.
Copy (data.Data)
@ -73,3 +80,12 @@ type MainWindow interface {
// be manually overridden.
NewPanel (bounds image.Rectangle) (Window, error)
}
// MenuWindow is a temporary window that automatically closes when the user
// presses escape or clicks outside of it.
type MenuWindow interface {
Window
// Pin converts this window into a panel, pinning it to the screen.
Pin ()
}