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" // import "runtime/debug"
type mainWindow struct { *window } type mainWindow struct { *window }
type menuWindow struct { *window }
type window struct { type window struct {
backend *Backend backend *Backend
xWindow *xwindow.Window xWindow *xwindow.Window
@ -48,13 +49,14 @@ func (backend *Backend) NewWindow (
err error, err error,
) { ) {
if backend == nil { panic("nil backend") } if backend == nil { panic("nil backend") }
window, err := backend.newWindow(bounds) window, err := backend.newWindow(bounds, false)
output = mainWindow { window } output = mainWindow { window }
return output, err return output, err
} }
func (backend *Backend) newWindow ( func (backend *Backend) newWindow (
bounds image.Rectangle, bounds image.Rectangle,
override bool,
) ( ) (
output *window, output *window,
err error, err error,
@ -66,10 +68,19 @@ func (backend *Backend) newWindow (
window.xWindow, err = xwindow.Generate(backend.connection) window.xWindow, err = xwindow.Generate(backend.connection)
if err != nil { return } if err != nil { return }
err = window.xWindow.CreateChecked (
backend.connection.RootWin(), if override {
bounds.Min.X, bounds.Min.Y, bounds.Dx(), bounds.Dy(), 0) 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 } if err != nil { return }
err = window.xWindow.Listen ( err = window.xWindow.Listen (
xproto.EventMaskExposure, xproto.EventMaskExposure,
xproto.EventMaskStructureNotify, xproto.EventMaskStructureNotify,
@ -252,7 +263,8 @@ func (window *window) SetIcon (sizes []image.Image) {
} }
func (window *window) NewModal (bounds image.Rectangle) (tomo.Window, error) { 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 ( icccm.WmTransientForSet (
window.backend.connection, window.backend.connection,
modal.xWindow.Id, modal.xWindow.Id,
@ -267,8 +279,24 @@ func (window *window) NewModal (bounds image.Rectangle) (tomo.Window, error) {
return modal, err 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) { 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 } if err != nil { return nil, err }
panel.setClientLeader(window.window) panel.setClientLeader(window.window)
window.setClientLeader(window.window) window.setClientLeader(window.window)
@ -281,6 +309,10 @@ func (window mainWindow) NewPanel (bounds image.Rectangle) (tomo.Window, error)
return panel, err return panel, err
} }
func (window menuWindow) Pin () {
// TODO
}
func (window *window) inheritProperties (parent *window) { func (window *window) inheritProperties (parent *window) {
window.SetApplicationName(parent.application) window.SetApplicationName(parent.application)
} }

View File

@ -38,6 +38,13 @@ type Window interface {
// window, but this position may be overridden by the backend or // window, but this position may be overridden by the backend or
// operating system. // operating system.
NewModal (bounds image.Rectangle) (Window, error) 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 puts data into the clipboard.
Copy (data.Data) Copy (data.Data)
@ -73,3 +80,12 @@ type MainWindow interface {
// be manually overridden. // be manually overridden.
NewPanel (bounds image.Rectangle) (Window, error) 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 ()
}