Пример #1
0
func (c *Client) Close() {
	if strIndex("WM_DELETE_WINDOW", c.protocols) > -1 {
		wm_protocols, err := xprop.Atm(wm.X, "WM_PROTOCOLS")
		if err != nil {
			logger.Warning.Println(err)
			return
		}

		wm_del_win, err := xprop.Atm(wm.X, "WM_DELETE_WINDOW")
		if err != nil {
			logger.Warning.Println(err)
			return
		}

		cm, err := xevent.NewClientMessage(32, c.Id(), wm_protocols,
			int(wm_del_win))
		if err != nil {
			logger.Warning.Println(err)
			return
		}

		err = xproto.SendEventChecked(wm.X.Conn(), false, c.Id(), 0,
			string(cm.Bytes())).Check()
		if err != nil {
			logger.Message.Printf("Could not send WM_DELETE_WINDOW "+
				"ClientMessage because: %s", err)
		}
	} else {
		c.win.Kill() // HULK SMASH!
	}
}
Пример #2
0
func Focus(c Client) {
	Remove(c)

	if c.CanFocus() || c.SendFocusNotify() {
		Clients = append(Clients, c)
		c.PrepareForFocus()
		c.Focused()
	}
	if c.CanFocus() {
		c.Win().Focus()
	}
	if c.SendFocusNotify() {
		protsAtm, err := xprop.Atm(X, "WM_PROTOCOLS")
		if err != nil {
			logger.Warning.Println(err)
			return
		}

		takeFocusAtm, err := xprop.Atm(X, "WM_TAKE_FOCUS")
		if err != nil {
			logger.Warning.Println(err)
			return
		}

		cm, err := xevent.NewClientMessage(32, c.Id(), protsAtm,
			int(takeFocusAtm), int(X.TimeGet()))
		if err != nil {
			logger.Warning.Println(err)
			return
		}

		xproto.SendEvent(X.Conn(), false, c.Id(), 0, string(cm.Bytes()))
	}
}
Пример #3
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")
}
Пример #4
0
func (m *TrayManager) RequireManageTrayIcons() {
	mstype, err := xprop.Atm(TrayXU, "MANAGER")
	if err != nil {
		logger.Warning("Get MANAGER Failed")
		return
	}

	timeStamp, _ := ewmh.WmUserTimeGet(TrayXU, m.owner)
	cm, err := xevent.NewClientMessage(
		32,
		TrayXU.RootWin(),
		mstype,
		int(timeStamp),
		int(_NET_SYSTEM_TRAY_S0),
		int(m.owner),
	)

	if err != nil {
		logger.Warning("Send MANAGER Request failed:", err)
		return
	}

	// !!! ewmh.ClientEvent not use EventMaskStructureNotify.
	xevent.SendRootEvent(TrayXU, cm,
		uint32(xproto.EventMaskStructureNotify))
}
func newFullScreenWorkaround() *fullScreenWorkaround {
	XU, _ := xgbutil.NewConn()
	ACTIVE_WINDOW, _ := xprop.Atm(XU, "_NET_ACTIVE_WINDOW")
	w := &fullScreenWorkaround{
		XU, []string{"libflash", "chrome", "mplayer", "operaplugin", "soffice", "wpp", "evince", "vlc", "totem"}, ACTIVE_WINDOW, false,
	}
	return w
}
Пример #6
0
// _NET_WM_SYNC_REQUEST req extra
func WmSyncRequestExtra(xu *xgbutil.XUtil, win xproto.Window, reqNum uint64,
	time xproto.Timestamp) error {

	syncReq, err := xprop.Atm(xu, "_NET_WM_SYNC_REQUEST")
	if err != nil {
		return err
	}

	high := int(reqNum >> 32)
	low := int(reqNum<<32 ^ reqNum)

	return ClientEvent(xu, win, "WM_PROTOCOLS", int(syncReq), int(time),
		low, high)
}
Пример #7
0
// announce sends a ClientMessage event to the root window to let everyone
// know that Wingo is the boss. (As per ICCCM 2.8.)
func announce(X *xgbutil.XUtil) {
	typAtom, err := xprop.Atm(X, "MANAGER")
	if err != nil {
		logger.Warning.Println(err)
		return
	}
	manSelAtom, err := managerAtom(X)
	if err != nil {
		logger.Warning.Println(err)
		return
	}
	cm, err := xevent.NewClientMessage(32, X.RootWin(), typAtom,
		int(X.TimeGet()), int(manSelAtom), int(X.Dummy()))
	xproto.SendEvent(X.Conn(), false, X.RootWin(),
		xproto.EventMaskStructureNotify, string(cm.Bytes()))
}
Пример #8
0
// ClientEvent is a convenience function that sends ClientMessage events
// to the root window as specified by the EWMH spec.
func ClientEvent(xu *xgbutil.XUtil, window xproto.Window, messageType string,
	data ...interface{}) error {

	mstype, err := xprop.Atm(xu, messageType)
	if err != nil {
		return err
	}

	evMask := (xproto.EventMaskSubstructureNotify |
		xproto.EventMaskSubstructureRedirect)
	cm, err := xevent.NewClientMessage(32, window, mstype, data...)
	if err != nil {
		return err
	}

	return xevent.SendRootEvent(xu, cm, uint32(evMask))
}
Пример #9
0
// _NET_WM_PING req extra
func WmPingExtra(xu *xgbutil.XUtil, win xproto.Window, response bool,
	time xproto.Timestamp) error {

	pingAtom, err := xprop.Atm(xu, "_NET_WM_PING")
	if err != nil {
		return err
	}

	var evWindow xproto.Window
	if response {
		evWindow = xu.RootWin()
	} else {
		evWindow = win
	}

	return ClientEvent(xu, evWindow, "WM_PROTOCOLS", int(pingAtom), int(time),
		int(win))
}
Пример #10
0
// managerAtom returns an xproto.Atom of the manager selection atom.
// Usually it's "WM_S0", where "0" is the screen number.
func managerAtom(X *xgbutil.XUtil) (xproto.Atom, error) {
	name := fmt.Sprintf("WM_S%d", X.Conn().DefaultScreen)
	return xprop.Atm(X, name)
}
Пример #11
0
func initAtom() {
	_NET_SHOWING_DESKTOP, _ = xprop.Atm(XU, "_NET_SHOWING_DESKTOP")
	DEEPIN_SCREEN_VIEWPORT, _ = xprop.Atm(XU, "DEEPIN_SCREEN_VIEWPORT")
	_NET_CLIENT_LIST, _ = xprop.Atm(XU, "_NET_CLIENT_LIST")
	_NET_ACTIVE_WINDOW, _ = xprop.Atm(XU, "_NET_ACTIVE_WINDOW")
	ATOM_WINDOW_ICON, _ = xprop.Atm(XU, "_NET_WM_ICON")
	ATOM_WINDOW_NAME, _ = xprop.Atm(XU, "_NET_WM_NAME")
	ATOM_WINDOW_STATE, _ = xprop.Atm(XU, "_NET_WM_STATE")
	ATOM_WINDOW_TYPE, _ = xprop.Atm(XU, "_NET_WM_WINDOW_TYPE")
	ATOM_DOCK_APP_ID, _ = xprop.Atm(XU, "_DDE_DOCK_APP_ID")

	_NET_SYSTEM_TRAY_S0, _ = xprop.Atm(TrayXU, "_NET_SYSTEM_TRAY_S0")
	_NET_SYSTEM_TRAY_OPCODE, _ = xprop.Atm(TrayXU, "_NET_SYSTEM_TRAY_OPCODE")
}