Beispiel #1
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
}
Beispiel #2
0
func main() {
	X, _ := xgbutil.NewConn()

	active, err := ewmh.ActiveWindowGet(X)

	wmName, err := icccm.WmNameGet(X, active)
	showTest("WM_NAME get", wmName, err)

	err = icccm.WmNameSet(X, active, "hooblah")
	wmName, _ = icccm.WmNameGet(X, active)
	showTest("WM_NAME set", wmName, err)

	wmNormHints, err := icccm.WmNormalHintsGet(X, active)
	showTest("WM_NORMAL_HINTS get", wmNormHints, err)

	wmNormHints.Width += 5
	err = icccm.WmNormalHintsSet(X, active, wmNormHints)
	showTest("WM_NORMAL_HINTS set", wmNormHints, err)

	wmHints, err := icccm.WmHintsGet(X, active)
	showTest("WM_HINTS get", wmHints, err)

	wmHints.InitialState = icccm.StateNormal
	err = icccm.WmHintsSet(X, active, wmHints)
	showTest("WM_NORMAL_HINTS set", wmHints, err)

	wmClass, err := icccm.WmClassGet(X, active)
	showTest("WM_CLASS get", wmClass, err)

	wmClass.Instance = "hoopdy hoop"
	err = icccm.WmClassSet(X, active, wmClass)
	showTest("WM_CLASS set", wmClass, err)

	wmTrans, err := icccm.WmTransientForGet(X, active)
	showTest("WM_TRANSIENT_FOR get", wmTrans, err)

	wmProts, err := icccm.WmProtocolsGet(X, active)
	showTest("WM_PROTOCOLS get", wmProts, err)

	wmClient, err := icccm.WmClientMachineGet(X, active)
	showTest("WM_CLIENT_MACHINE get", wmClient, err)

	err = icccm.WmClientMachineSet(X, active, "Leopard")
	wmClient, _ = icccm.WmClientMachineGet(X, active)
	showTest("WM_CLIENT_MACHINE set", wmClient, err)

	wmState, err := icccm.WmStateGet(X, active)
	showTest("WM_STATE get", wmState, err)

	wmState.Icon = xproto.Window(8365538)
	wmState.State = icccm.StateNormal
	err = icccm.WmStateSet(X, active, wmState)
	wmState, _ = icccm.WmStateGet(X, active)
	showTest("WM_STATE set", wmState, err)
}
Beispiel #3
0
// WMTakeFocus will do all the necessary setup to support the WM_TAKE_FOCUS
// protocol using the "LocallyActive" input model described in Section 4.1.7
// of the ICCCM. Namely, listening to ClientMessage events and running the
// callback function provided when a WM_TAKE_FOCUS ClientMessage has been
// received.
//
// Typically, the callback function should include a call to SetInputFocus
// with the "Parent" InputFocus type, the sub-window id of the window that
// should have focus, and the 'tstamp' timestamp.
func (w *Window) WMTakeFocus(cb func(w *Window, tstamp xproto.Timestamp)) {
	// Make sure the Input flag is set to true in WM_HINTS. We first
	// must retrieve the current WM_HINTS, so we don't overwrite the flags.
	curFlags := 0
	if hints, err := icccm.WmHintsGet(w.X, w.Id); err == nil {
		curFlags = hints.Flags
	}
	icccm.WmHintsSet(w.X, w.Id, &icccm.Hints{
		Flags: curFlags | icccm.HintInput,
		Input: 1,
	})

	// Get the current protocols so we don't overwrite anything.
	prots, _ := icccm.WmProtocolsGet(w.X, w.Id)

	// If WM_TAKE_FOCUS isn't here, add it. Otherwise, move on.
	wmfocus := false
	for _, prot := range prots {
		if prot == "WM_TAKE_FOCUS" {
			wmfocus = true
			break
		}
	}
	if !wmfocus {
		icccm.WmProtocolsSet(w.X, w.Id, append(prots, "WM_TAKE_FOCUS"))
	}

	// Attach a ClientMessage event handler. It will determine whether the
	// ClientMessage is a 'focus' request, and if so, run the callback 'cb'
	// provided.
	xevent.ClientMessageFun(
		func(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) {
			if icccm.IsFocusProtocol(X, ev) {
				cb(w, xproto.Timestamp(ev.Data.Data32[1]))
			}
		}).Connect(w.X, w.Id)
}