Exemplo n.º 1
0
func newWindow(X *xgbutil.XUtil) {
	win, err := xwindow.Generate(X)
	if err != nil {
		log.Fatal(err)
	}
	win.Create(X.RootWin(), 0, 0, 200, 200,
		xproto.CwBackPixel|xproto.CwEventMask,
		0, xproto.EventMaskButtonRelease)
	win.WMGracefulClose(
		func(w *xwindow.Window) {
			xevent.Detach(w.X, w.Id)
			mousebind.Detach(w.X, w.Id)
			w.Destroy()
			xevent.Quit(X)
			Done <- true
		})

	win.Map()

	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)
	}
}
Exemplo n.º 2
0
// _NET_DESKTOP_LAYOUT set
func DesktopLayoutSet(xu *xgbutil.XUtil, orientation, columns, rows,
	startingCorner uint) error {

	return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_DESKTOP_LAYOUT",
		"CARDINAL", orientation, columns, rows,
		startingCorner)
}
Exemplo n.º 3
0
// RootGeometry gets the geometry of the root window. It will panic on failure.
func RootGeometry(xu *xgbutil.XUtil) xrect.Rect {
	geom, err := RawGeometry(xu, xproto.Drawable(xu.RootWin()))
	if err != nil {
		panic(err)
	}
	return geom
}
Exemplo n.º 4
0
Arquivo: shape.go Projeto: justjake/j3
// compose a number of rectabgles into a window shape
func ComposeShape(X *xgbutil.XUtil, dst xproto.Window, rects []xrect.Rect) (err error) {

	combine_bounds := make([]shape.CombineCookie, len(rects))
	combine_clip := make([]shape.CombineCookie, len(rects))

	var operation shape.Op

	for i, rect := range rects {
		// make rectangular window of correct goemetry
		win, err := xwindow.Generate(X)
		if err != nil {
			log.Fatalf("ComposeShape: Error creating rectange %v window.", rect)
			return err
		}
		win.Create(X.RootWin(), rect.X(), rect.Y(), rect.Width(), rect.Height(), xproto.CwBackPixel, 0xffffff)

		// choose operation. on the first one, we want to set the shape.
		if i == 0 {
			operation = shape.SoSet
		} else {
			operation = shape.SoUnion
		}

		// combine window request
		x, y := int16(rect.X()), int16(rect.Y())

		combine_kind := shape.Kind(shape.SkBounding)
		combine_bounds[i] = shape.CombineChecked(X.Conn(), operation, combine_kind, combine_kind, dst, x, y, win.Id)
		combine_kind = shape.Kind(shape.SkClip)
		combine_clip[i] = shape.CombineChecked(X.Conn(), operation, combine_kind, combine_kind, dst, x, y, win.Id)
	}
	return nil
}
Exemplo n.º 5
0
// New allocates and initializes a new DockApp.  NewDockApp does not initialize
// the window contents and does not map the window to the display screen.  The
// window is mapped to the screen when the Main method is called on the
// returned DockApp.
func New(x *xgbutil.XUtil, rect image.Rectangle) (*DockApp, error) {
	win, err := xwindow.Generate(x)
	if err != nil {
		log.Fatalf("generate window: %v", err)
	}
	win.Create(x.RootWin(), 0, 0, rect.Size().X, rect.Size().Y, 0)

	// Set WM hints so that Openbox puts the window into the dock.
	hints := &icccm.Hints{
		Flags:        icccm.HintState | icccm.HintIconWindow,
		InitialState: icccm.StateWithdrawn,
		IconWindow:   win.Id,
		WindowGroup:  win.Id,
	}
	err = icccm.WmHintsSet(x, win.Id, hints)
	if err != nil {
		win.Destroy()
		return nil, fmt.Errorf("wm hints: %v", err)
	}
	img := xgraphics.New(x, rect)
	err = img.XSurfaceSet(win.Id)
	if err != nil {
		img.Destroy()
		win.Destroy()
		return nil, fmt.Errorf("xsurface set: %v", err)
	}
	app := &DockApp{
		x:   x,
		img: img,
		win: win,
	}
	return app, nil
}
Exemplo n.º 6
0
func newParent(X *xgbutil.XUtil, cid xproto.Window) (*Parent, error) {
	parent, err := xwindow.Generate(X)
	if err != nil {
		logger.Error.Printf("Could not create a parent window for client "+
			"with id '%d' because: %s", cid, err)
		logger.Error.Fatalf("In a state where no new windows can be created. " +
			"Unfortunately, we must exit.")
	}

	err = parent.CreateChecked(X.RootWin(), 0, 0, 1, 1,
		xproto.CwEventMask,
		xproto.EventMaskSubstructureRedirect|
			xproto.EventMaskButtonPress|xproto.EventMaskButtonRelease)
	if err != nil {
		return nil, err
	}

	err = xproto.ReparentWindowChecked(X.Conn(),
		cid, parent.Id, 0, 0).Check()
	if err != nil {
		return nil, err
	}

	return &Parent{parent}, nil
}
Exemplo n.º 7
0
func newWindow(controlCh *controlCh, X *xgbutil.XUtil, width, height int) *xwindow.Window {
	var (
		err error
		win *xwindow.Window
	)

	win, err = xwindow.Generate(X)
	if err != nil {
		panic(err)
	}

	win.Create(X.RootWin(), 0, 0, width, height,
		xproto.CwBackPixel|xproto.CwEventMask,
		0, xproto.EventMaskButtonRelease)

	// Xorg application exits when the window is closed.
	win.WMGracefulClose(
		func(w *xwindow.Window) {
			xevent.Detach(w.X, w.Id)
			mousebind.Detach(w.X, w.Id)
			w.Destroy()
			xevent.Quit(X)
			controlCh.exit <- true
		})

	// In order to get ConfigureNotify events, we must listen to the window
	// using the 'StructureNotify' mask.
	win.Listen(xproto.EventMaskButtonPress |
		xproto.EventMaskButtonRelease |
		xproto.EventMaskKeyPress |
		xproto.EventMaskKeyRelease |
		xproto.EventMaskStructureNotify)
	win.Map()
	return win
}
Exemplo n.º 8
0
Arquivo: mouse.go Projeto: justjake/j3
// find the EWHM window under the mouse cursor
func FindManagedWindowUnderMouse(X *xgbutil.XUtil) (xproto.Window, error) {
	// construct a hashset of the managed windows
	clients, err := ewmh.ClientListGet(X)
	if err != nil {
		return 0, fmt.Errorf("FindUnderMouse: could not retrieve EWHM client list: %v", err)
	}

	managed := make(map[xproto.Window]bool, len(clients))
	for _, win := range clients {
		managed[win] = true
	}

	cur_window := X.RootWin()

	// descend the QueryTree to the first child that is a EWMH managed window
	for {
		// return the parent if it is an EWHM window
		if _, ok := managed[cur_window]; ok {
			return cur_window, nil
		}

		cur_window, _, err = FindNextUnderMouse(X, cur_window)
		if err != nil {
			break
		}
	}

	// we didn't find the window :(
	return 0, errors.New("FindUnderMouse: no EWMH window found under mouse")
}
Exemplo n.º 9
0
func newAudio(Xu *xgbutil.XUtil) (*audio, error) {
	m, err := OpenMixer()
	if err != nil {
		return nil, err
	}
	defer func() {
		// set m to nil on final success
		if m != nil {
			_ = m.Close()
		}
	}()

	a := &audio{
		mixer: m,
	}

	for _, k := range []struct {
		key string
		fn  keybind.KeyPressFun
	}{
		{"XF86AudioRaiseVolume", a.up},
		{"XF86AudioLowerVolume", a.down},
		{"XF86AudioMute", a.mute},
	} {
		if err := k.fn.Connect(Xu, Xu.RootWin(), k.key, true); err != nil {
			return nil, err
		}
	}

	m = nil
	return a, nil
}
Exemplo n.º 10
0
func newWindow(X *xgbutil.XUtil, width, height int) *xwindow.Window {
	var (
		err error
		win *xwindow.Window
	)
	win, err = xwindow.Generate(X)
	if err != nil {
		log.Fatal(err)
	}
	win.Create(X.RootWin(), 0, 0, width, height,
		xproto.CwBackPixel|xproto.CwEventMask,
		0, xproto.EventMaskButtonRelease)
	win.WMGracefulClose(
		func(w *xwindow.Window) {
			xevent.Detach(w.X, w.Id)
			mousebind.Detach(w.X, w.Id)
			w.Destroy()
			xevent.Quit(X)
		})

	win.Map()

	if err != nil {
		log.Fatal(err)
	}
	return win
}
Exemplo n.º 11
0
Arquivo: cross.go Projeto: justjake/j3
// When a cross is declared in its object literal form, it may not have the appropriate window.
// this function creates a new X11 window for the cross with the correct geometry depending
// on its Icon* parameters.
func (c *Cross) CreateWindow(X *xgbutil.XUtil, icons_per_direction int, bg_color uint32) (*xwindow.Window, error) {

	// calculate the dimensions of the spars of our cross +
	// width/height reflect the vertical-orientation rectangle
	width := c.IconMargin*2 + c.IconSize
	// padding between the icons, margin on the edges
	height := c.IconSize*icons_per_direction + c.IconPadding*(icons_per_direction-1) + c.IconMargin*2

	// intitialize a basic window for the cross
	win, err := xwindow.Generate(X)
	if err != nil {
		return nil, err
	}

	win.Create(X.RootWin(), 0, 0, height, height,
		xproto.CwBackPixel|xproto.CwOverrideRedirect, bg_color, 1)

	// the rects we will be adding together to form the shape of the cross
	vert := xrect.New(0, 0, width, height)
	horiz := xrect.New(0, 0, height, width)
	struts := []xrect.Rect{vert, horiz}

	geom, err := win.Geometry()
	if err != nil {
		return nil, err
	}

	// center struts over window
	x, y := util.CenterChild(vert, geom)
	vert.XSet(x)
	vert.YSet(y)
	x, y = util.CenterChild(horiz, geom)
	horiz.XSet(x)
	horiz.YSet(y)

	// build the cross shape from our friendly rectangles
	err = ComposeShape(X, win.Id, struts)
	if err != nil {
		return nil, err
	}

	// add the window to our cross struct
	c.Window = win

	// create icons from our images
	clr := RGB(bg_color)
	if c.imagesToBecomeIcons != nil {
		icons := make(map[string]*Icon, len(c.imagesToBecomeIcons))
		for name, img := range c.imagesToBecomeIcons {
			icon := NewIcon(X, img, win.Id)
			icon.Background = clr
			icons[name] = icon
		}
		c.Icons = icons
	} else {
		return nil, errors.New("Cross: you must create crosses using the NewCross function (this cross has now iconsToBecomeImage)")
	}

	return win, nil
}
Exemplo n.º 12
0
func keyHandlers(X *xgbutil.XUtil,
	cycle *prompt.Cycle, items []*prompt.CycleItem) {

	geom := headGeom(X)

	keybind.KeyPressFun(
		func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
			shown := cycle.Show(geom, cycleNext, items)
			if !shown {
				log.Fatal("Did not show cycle prompt.")
			}
			cycle.Next()
		}).Connect(X, X.RootWin(), cycleNext, true)
	keybind.KeyPressFun(
		func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
			cycle.Next()
		}).Connect(X, cycle.GrabId(), cycleNext, true)

	keybind.KeyPressFun(
		func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
			shown := cycle.Show(geom, cyclePrev, items)
			if !shown {
				log.Fatal("Did not show cycle prompt.")
			}
			cycle.Prev()
		}).Connect(X, X.RootWin(), cyclePrev, true)
	keybind.KeyPressFun(
		func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
			cycle.Prev()
		}).Connect(X, cycle.GrabId(), cyclePrev, true)
}
Exemplo n.º 13
0
func bind(Xu *xgbutil.XUtil, bindings ...binding) error {
	for _, k := range bindings {
		if err := k.fn.Connect(Xu, Xu.RootWin(), k.key, true); err != nil {
			return err
		}
	}
	return nil
}
Exemplo n.º 14
0
// sendClientMessages is a goroutine that sends client messages to the root
// window. We then listen to them later as a demonstration of responding to
// X events. (They are sent with SubstructureNotify and SubstructureRedirect
// masks set. So in order to receive them, we'll have to explicitly listen
// to events of that type on the root window.)
func xSource(X *xgbutil.XUtil) {
	i := 1
	for {
		ewmh.ClientEvent(X, X.RootWin(), "NOOP", i)
		i++
		time.Sleep(200 * time.Millisecond)
	}
}
Exemplo n.º 15
0
// _NET_DESKTOP_GEOMETRY get
func DesktopGeometryGet(xu *xgbutil.XUtil) (*DesktopGeometry, error) {
	geom, err := xprop.PropValNums(xprop.GetProperty(xu, xu.RootWin(),
		"_NET_DESKTOP_GEOMETRY"))
	if err != nil {
		return nil, err
	}

	return &DesktopGeometry{Width: int(geom[0]), Height: int(geom[1])}, nil
}
Exemplo n.º 16
0
// _NET_DESKTOP_NAMES set
func DesktopNamesSet(xu *xgbutil.XUtil, names []string) error {
	nullterm := make([]byte, 0)
	for _, name := range names {
		nullterm = append(nullterm, name...)
		nullterm = append(nullterm, 0)
	}
	return xprop.ChangeProp(xu, xu.RootWin(), 8, "_NET_DESKTOP_NAMES",
		"UTF8_STRING", nullterm)
}
Exemplo n.º 17
0
// _NET_SUPPORTED set
// This will create any atoms in the argument if they don't already exist.
func SupportedSet(xu *xgbutil.XUtil, atomNames []string) error {
	atoms, err := xprop.StrToAtoms(xu, atomNames)
	if err != nil {
		return err
	}

	return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_SUPPORTED", "ATOM",
		atoms...)
}
Exemplo n.º 18
0
// _NET_SHOWING_DESKTOP req
func ShowingDesktopReq(xu *xgbutil.XUtil, show bool) error {
	var showInt uint
	if show {
		showInt = 1
	} else {
		showInt = 0
	}
	return ClientEvent(xu, xu.RootWin(), "_NET_SHOWING_DESKTOP", showInt)
}
Exemplo n.º 19
0
func NewInput(X *xgbutil.XUtil, theme *InputTheme, config InputConfig) *Input {
	input := &Input{
		X:       X,
		theme:   theme,
		config:  config,
		showing: false,
		do:      nil,
		history: make([]string, 0, 100),
	}

	// Create all windows used for the base of the input prompt.
	cwin := func(p xproto.Window) *xwindow.Window {
		return xwindow.Must(xwindow.Create(X, p))
	}
	input.win = cwin(X.RootWin())
	input.label = cwin(input.win.Id)
	input.input = text.NewInput(X, input.win.Id, 1000, theme.Padding,
		theme.Font, theme.FontSize, theme.FontColor, theme.BgColor)
	input.bInp = cwin(input.win.Id)
	input.bTop, input.bBot = cwin(input.win.Id), cwin(input.win.Id)
	input.bLft, input.bRht = cwin(input.win.Id), cwin(input.win.Id)

	// Make the top-level window override redirect so the window manager
	// doesn't mess with us.
	input.win.Change(xproto.CwOverrideRedirect, 1)
	input.win.Listen(xproto.EventMaskFocusChange)
	input.input.Listen(xproto.EventMaskKeyPress)

	// Colorize the windows.
	cclr := func(w *xwindow.Window, clr render.Color) {
		w.Change(xproto.CwBackPixel, clr.Uint32())
	}
	cclr(input.win, input.theme.BgColor)
	cclr(input.bInp, input.theme.BorderColor)
	cclr(input.bTop, input.theme.BorderColor)
	cclr(input.bBot, input.theme.BorderColor)
	cclr(input.bLft, input.theme.BorderColor)
	cclr(input.bRht, input.theme.BorderColor)

	// Map the sub-windows once.
	input.label.Map()
	input.input.Map()
	input.bInp.Map()
	input.bTop.Map()
	input.bBot.Map()
	input.bLft.Map()
	input.bRht.Map()

	// Connect the key response handler.
	// The handler is responsible for tab completion and quitting if the
	// cancel key has been pressed.
	input.keyResponse().Connect(X, input.input.Id)
	input.focusResponse().Connect(X, input.win.Id)

	return input
}
Exemplo n.º 20
0
func (hotkey Hotkey) attach(X *xgbutil.XUtil) {
	log.Println(hotkey.Key)
	err := keybind.KeyPressFun(
		func(X *xgbutil.XUtil, e xevent.KeyPressEvent) {
			go exec.Command("/bin/sh", "-c", hotkey.Cmd).Run()
		}).Connect(X, X.RootWin(), hotkey.Key, true)
	if err != nil {
		log.Fatalf("Could not bind %s: %s", hotkey.Key, err.Error())
	}
}
Exemplo n.º 21
0
// _NET_WM_HANDLED_ICONS set
func WmHandledIconsSet(xu *xgbutil.XUtil, handle bool) error {
	var handled uint
	if handle {
		handled = 1
	} else {
		handled = 0
	}
	return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_WM_HANDLED_ICONS",
		"CARDINAL", handled)
}
Exemplo n.º 22
0
// _NET_DESKTOP_VIEWPORT set
func DesktopViewportSet(xu *xgbutil.XUtil, viewports []DesktopViewport) error {
	coords := make([]uint, len(viewports)*2)
	for i, viewport := range viewports {
		coords[i*2] = uint(viewport.X)
		coords[i*2+1] = uint(viewport.Y)
	}

	return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_DESKTOP_VIEWPORT",
		"CARDINAL", coords...)
}
Exemplo n.º 23
0
// _NET_SHOWING_DESKTOP set
func ShowingDesktopSet(xu *xgbutil.XUtil, show bool) error {
	var showInt uint
	if show {
		showInt = 1
	} else {
		showInt = 0
	}
	return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_SHOWING_DESKTOP",
		"CARDINAL", showInt)
}
Exemplo n.º 24
0
func headGeom(X *xgbutil.XUtil) xrect.Rect {
	if X.ExtInitialized("XINERAMA") {
		heads, err := xinerama.PhysicalHeads(X)
		if err == nil {
			return heads[0]
		}
	}

	geom, err := xwindow.New(X, X.RootWin()).Geometry()
	fatal(err)
	return geom
}
Exemplo n.º 25
0
func StatusSet(X *xgbutil.XUtil, status bool) {
	var statusStr string
	if status {
		statusStr = "Success"
	} else {
		statusStr = "Error"
	}

	// throw away the error
	xprop.ChangeProp(X, X.RootWin(), 8, "_WINGO_CMD_STATUS", "UTF8_STRING",
		[]byte(statusStr))
}
Exemplo n.º 26
0
// _NET_WORKAREA set
func WorkareaSet(xu *xgbutil.XUtil, workareas []Workarea) error {
	rects := make([]uint, len(workareas)*4)
	for i, workarea := range workareas {
		rects[i*4+0] = uint(workarea.X)
		rects[i*4+1] = uint(workarea.Y)
		rects[i*4+2] = workarea.Width
		rects[i*4+3] = workarea.Height
	}

	return xprop.ChangeProp32(xu, xu.RootWin(), "_NET_WORKAREA", "CARDINAL",
		rects...)
}
Exemplo n.º 27
0
// 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)
	}
}
Exemplo n.º 28
0
// currentTime forcefully causes a PropertyNotify event to fire on the root
// window, then scans the event queue and picks up the time.
//
// It is NOT SAFE to call this function in a place other than Wingo's
// initialization. Namely, this function subverts xevent's queue and reads
// events directly from X.
func currentTime(X *xgbutil.XUtil) (xproto.Timestamp, error) {
	wmClassAtom, err := xprop.Atm(X, "WM_CLASS")
	if err != nil {
		return 0, err
	}

	stringAtom, err := xprop.Atm(X, "STRING")
	if err != nil {
		return 0, err
	}

	// Make sure we're listening to PropertyChange events on the root window.
	err = xwindow.New(X, X.RootWin()).Listen(xproto.EventMaskPropertyChange)
	if err != nil {
		return 0, fmt.Errorf(
			"Could not listen to Root window events (PropertyChange): %s", err)
	}

	// Do a zero-length append on a property as suggested by ICCCM 2.1.
	err = xproto.ChangePropertyChecked(
		X.Conn(), xproto.PropModeAppend, X.RootWin(),
		wmClassAtom, stringAtom, 8, 0, nil).Check()
	if err != nil {
		return 0, err
	}

	// Now look for the PropertyNotify generated by that zero-length append
	// and return the timestamp attached to that event.
	// Note that we do this outside of xgbutil/xevent, since ownership
	// is literally the first thing we do after connecting to X.
	// (i.e., we don't have our event handling system initialized yet.)
	timeout := time.After(3 * time.Second)
	for {
		select {
		case <-timeout:
			return 0, fmt.Errorf(
				"Expected a PropertyNotify event to get a valid timestamp, " +
					"but never received one.")
		default:
			ev, err := X.Conn().PollForEvent()
			if err != nil {
				continue
			}
			if propNotify, ok := ev.(xproto.PropertyNotifyEvent); ok {
				X.TimeSet(propNotify.Time) // why not?
				return propNotify.Time, nil
			}
			time.Sleep(100 * time.Millisecond)
		}
	}
	panic("unreachable")
}
Exemplo n.º 29
0
// SetRoot sets the given background as the root window background.
func SetRoot(X *xgbutil.XUtil, bg *xgraphics.Image) error {
	root := X.RootWin()
	if err := bg.XSurfaceSet(root); err != nil {
		return err
	}
	bg.XDraw()
	bg.XPaint(root)
	// FIXME: This doesn't set the pixmap persistently. As soon as the program
	// exits, the pixmap is destroyed. Find a way to make it persistent.
	xprop.ChangeProp32(X, root, "_XROOTPMAP_ID", "PIXMAP", uint(bg.Pixmap))
	xprop.ChangeProp32(X, root, "ESETROOT_PMAP_ID", "PIXMAP", uint(bg.Pixmap))
	return nil
}
Exemplo n.º 30
0
// _NET_SHOWING_DESKTOP get
func ShowingDesktopGet(xu *xgbutil.XUtil) (bool, error) {
	reply, err := xprop.GetProperty(xu, xu.RootWin(), "_NET_SHOWING_DESKTOP")
	if err != nil {
		return false, err
	}

	val, err := xprop.PropValNum(reply, nil)
	if err != nil {
		return false, err
	}

	return val == 1, nil
}