// newWindow creates a new window with a random background color. It sets the // WM_PROTOCOLS property to contain the WM_DELETE_WINDOW atom. It also sets // up a ClientMessage event handler so that we know when to destroy the window. // We also set up a mouse binding so that clicking inside a window will // create another one. func newWindow(X *xgbutil.XUtil) { counter++ win, err := xwindow.Generate(X) if err != nil { log.Fatal(err) } // Get a random background color, create the window (ask to receive button // release events while we're at it) and map the window. bgColor := rand.Intn(0xffffff + 1) win.Create(X.RootWin(), 0, 0, 200, 200, xproto.CwBackPixel|xproto.CwEventMask, uint32(bgColor), xproto.EventMaskButtonRelease) // WMGracefulClose does all of the work for us. It sets the appropriate // values for WM_PROTOCOLS, and listens for ClientMessages that implement // the WM_DELETE_WINDOW protocol. When one is found, the provided callback // is executed. win.WMGracefulClose( func(w *xwindow.Window) { // Detach all event handlers. // This should always be done when a window can no longer // receive events. xevent.Detach(w.X, w.Id) mousebind.Detach(w.X, w.Id) w.Destroy() // Exit if there are no more windows left. counter-- if counter == 0 { os.Exit(0) } }) // It's important that the map comes after setting WMGracefulClose, since // the WM isn't obliged to watch updates to the WM_PROTOCOLS property. win.Map() // A mouse binding so that a left click will spawn a new window. // Note that we don't issue a grab here. Typically, window managers will // grab a button press on the client window (which usually activates the // window), so that we'd end up competing with the window manager if we // tried to grab it. // Instead, we set a ButtonRelease mask when creating the window and attach // a mouse binding *without* a grab. err = mousebind.ButtonReleaseFun( func(X *xgbutil.XUtil, ev xevent.ButtonReleaseEvent) { newWindow(X) }).Connect(X, win.Id, "1", false, false) if err != nil { log.Fatal(err) } }
func NewWindow(width, height int) (wde.Window, error) { var err error w := new(Window) w.width, w.height = width, height w.xu, err = xgbutil.NewConn() if err != nil { return nil, err } w.conn = w.xu.Conn() screen := w.xu.Screen() w.win, err = xwindow.Generate(w.xu) if err != nil { return nil, err } err = w.win.CreateChecked(screen.Root, 600, 500, width, height, 0) if err != nil { return nil, err } w.win.Listen(AllEventsMask) err = icccm.WmProtocolsSet(w.xu, w.win.Id, []string{"WM_DELETE_WINDOW"}) if err != nil { fmt.Println(err) err = nil } w.bufferLck = &sync.Mutex{} w.buffer = xgraphics.New(w.xu, image.Rect(0, 0, width, height)) w.buffer.XSurfaceSet(w.win.Id) keyMap, modMap := keybind.MapsGet(w.xu) keybind.KeyMapSet(w.xu, keyMap) keybind.ModMapSet(w.xu, modMap) w.events = make(chan interface{}) w.SetIcon(Gordon) w.SetIconName("Go") go w.handleEvents() return w, nil }
// newWindow creates a new window that listens to MotionNotify events with // the given backgroundcolor. func newWindow(X *xgbutil.XUtil, color uint32) *xwindow.Window { win, err := xwindow.Generate(X) if err != nil { log.Fatal(err) } err = win.CreateChecked(X.RootWin(), 0, 0, 400, 400, xproto.CwBackPixel|xproto.CwEventMask, color, xproto.EventMaskPointerMotion) if err != nil { log.Fatal(err) } win.Map() return win }
func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Create the cursor. You can find a list of available cursors in // xcursor/cursordef.go. // We'll make an umbrella here, with an orange foreground and a blue // background. (The background it typically the outline of the cursor.) // Note that each component of the RGB color is a 16 bit color. I think // using the most significant byte to specify each component is good // enough. cursor, err := xcursor.CreateCursorExtra(X, xcursor.Umbrella, 0xff00, 0x5500, 0x0000, 0x3300, 0x6600, 0xff00) if err != nil { log.Fatal(err) } // Create a new window. In the create window request, we'll set the // background color and set the cursor we created above. // This results in changing the cursor only when it moves into this window. win, err := xwindow.Generate(X) if err != nil { log.Fatal(err) } win.Create(X.RootWin(), 0, 0, 500, 500, xproto.CwBackPixel|xproto.CwCursor, 0xffffffff, uint32(cursor)) win.Map() // We can free the cursor now that we've set it. // If you plan on using this cursor again, then it shouldn't be freed. // (i.e., if you try to free this before setting it as the cursor in a // window, you'll get a BadCursor error when trying to use it.) xproto.FreeCursor(X.Conn(), cursor) // Block. No need to process any events. select {} }