From d710d13f0d5950fa88bbbcb90649d8a7af5c1608 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Fri, 24 Mar 2023 00:34:25 -0400 Subject: [PATCH] Added the ability to make different window types --- backend.go | 4 ++-- backends/x/window.go | 38 +++++++++++++++++++++++++++++++++++++- elements/window.go | 13 +++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/backend.go b/backend.go index a22e1ec..5d28c31 100644 --- a/backend.go +++ b/backend.go @@ -21,9 +21,9 @@ type Backend interface { Do (callback func ()) // NewWindow creates a new window with the specified width and height, - // and returns a struct representing it that fulfills the Window + // and returns a struct representing it that fulfills the MainWindow // interface. - NewWindow (width, height int) (window elements.Window, err error) + NewWindow (width, height int) (window elements.MainWindow, err error) // Copy puts data into the clipboard. Copy (data.Data) diff --git a/backends/x/window.go b/backends/x/window.go index 1eaa960..a851568 100644 --- a/backends/x/window.go +++ b/backends/x/window.go @@ -14,6 +14,7 @@ import "git.tebibyte.media/sashakoshka/tomo/canvas" import "git.tebibyte.media/sashakoshka/tomo/elements" // import "runtime/debug" +type mainWindow struct { *window } type window struct { backend *Backend xWindow *xwindow.Window @@ -35,11 +36,21 @@ type window struct { func (backend *Backend) NewWindow ( width, height int, ) ( - output elements.Window, + output elements.MainWindow, err error, ) { if backend == nil { panic("nil backend") } + window, err := backend.newWindow(width, height) + output = mainWindow { window } + return output, err +} +func (backend *Backend) newWindow ( + width, height int, +) ( + output *window, + err error, +) { window := &window { backend: backend } window.xWindow, err = xwindow.Generate(backend.connection) @@ -86,6 +97,7 @@ func (backend *Backend) NewWindow ( window.reallocateCanvas() backend.windows[window.xWindow.Id] = window + output = window return } @@ -195,6 +207,30 @@ func (window *window) SetIcon (sizes []image.Image) { wmIcons) } +func (window *window) NewModal (width, height int) (elements.Window, error) { + modal, err := window.backend.newWindow(width, height) + icccm.WmTransientForSet ( + window.backend.connection, + modal.xWindow.Id, + window.xWindow.Id) + ewmh.WmStateSet ( + window.backend.connection, + modal.xWindow.Id, + []string { "_NET_WM_STATE_MODAL" }) + return modal, err +} + +func (window mainWindow) NewPanel (width, height int) (elements.Window, error) { + panel, err := window.backend.newWindow(width, height) + hints, _ := icccm.WmHintsGet(window.backend.connection, panel.xWindow.Id) + hints.WindowGroup = window.xWindow.Id + icccm.WmHintsSet ( + window.backend.connection, + panel.xWindow.Id, + hints) + return panel, err +} + func (window *window) Show () { if window.child == nil { window.xCanvas.For (func (x, y int) xgraphics.BGRA { diff --git a/elements/window.go b/elements/window.go index 95f0f0c..7b432c3 100644 --- a/elements/window.go +++ b/elements/window.go @@ -25,6 +25,9 @@ type Window interface { // for some backends. SetIcon (sizes []image.Image) + // NewModal creates a new modal dialog window. + NewModal (width, height int) (window Window, err error) + // Show shows the window. The window starts off hidden, so this must be // called after initial setup to make sure it is visible. Show () @@ -38,3 +41,13 @@ type Window interface { // OnClose specifies a function to be called when the window is closed. OnClose (func ()) } + +// MainWindow is a window capable of owning multiple sub-windows. +type MainWindow interface { + Window + + // NewPanel creates a panel window that is semantically tied to this + // window. This is intended to be used for utility windows, tool bars, + // torn-off menus, etc. + NewPanel (width, height int) (window Window, err error) +}