BurntSushi / xgbutil

A utility library to make use of the X Go Binding easier. (Implements EWMH and ICCCM specs, key binding support, etc.)
Do What The F*ck You Want To Public License
194 stars 46 forks source link

xwindow.Create failed when the parent is a 32 depth window #19

Open snyh opened 10 years ago

snyh commented 10 years ago

I repeatedly read the man XWindowCreate, there hasn't a visual badmatch restrict.

For class InputOutput, the visual type and depth must be a combination supported for the screen, or a BadMatch error results. the code of xwindow.Create use RootDeapth and RootVisual, so it must be a combination supported for the screen.

below is the test code.

package main

import (
    "fmt"
    "github.com/BurntSushi/xgb/xproto"
    "github.com/BurntSushi/xgbutil"
    "github.com/BurntSushi/xgbutil/xwindow"
)

var XU, _ = xgbutil.NewConn()

func main() {
    visual := func() xproto.Visualid {
        for _, dinfo := range XU.Screen().AllowedDepths {
            for _, vinfo := range dinfo.Visuals {
                if dinfo.Depth == 32 {
                    return vinfo.VisualId
                }
            }
        }
        panic("can't found a Visual which support RGBA")
    }()
    rgbaWindow, _ := xwindow.Generate(XU)
    if err := xproto.CreateWindowChecked(XU.Conn(), 0, rgbaWindow.Id, XU.RootWin(), 0, 0, 1, 1, 0, xproto.WindowClassInputOnly, visual, 0, nil).Check(); err != nil {
        panic("Can't create an RGBA window by manual")
    }

    //this should be failed
    if _, err := xwindow.Create(XU, rgbaWindow.Id); err != nil {
        fmt.Println("Create Failed by xwindow.Create:", err)
    }

    //this should be ok
    child, _ := xwindow.Generate(XU)
    if err := xproto.CreateWindowChecked(XU.Conn(), 0, child.Id, rgbaWindow.Id, 0, 0, 1, 1, 0, xproto.WindowClassInputOnly, visual, 0, nil).Check(); err == nil {
        fmt.Println("Create OK by manual")

}

We can solve this by use parent's visualID (but it cost a xproto.GetWindowAttributes request) and 0 (CopyFromParent) for the depth. I don't know whether I understand all of the man XCreateWindow meanings, so I created this issue to hope you find out the way.

By the way, you use xproto.WindowClassCopyFromParent in the xwindow.Window.Create, same value but different semantic. (xcb use XCB_COPY_FROM_PARENT, may be you can manually define this variable in xgb )