Пример #1
0
func showSocketPath(X *xgbutil.XUtil) {
	currentWM, err := ewmh.GetEwmhWM(X)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	if strings.ToLower(currentWM) != "wingo" {
		fmt.Fprintf(os.Stderr, "Could not detect a Wingo instance. "+
			"(Found '%s' instead.)\n", currentWM)
		os.Exit(1)
	}
	fmt.Println(socketFilePath(X))
	os.Exit(0)
}
Пример #2
0
func main() {
	X, _ := xgbutil.NewConn()

	heads, err := xinerama.PhysicalHeads(X)
	if err != nil {
		fmt.Printf("ERROR: %v\n", err)
	} else {
		for i, head := range heads {
			fmt.Printf("%d - %v\n", i, head)
		}
	}

	wmName, err := ewmh.GetEwmhWM(X)
	if err != nil {
		fmt.Printf("ERROR: %v\n", err)
	} else {
		fmt.Printf("Window manager: %s\n", wmName)
	}
}
Пример #3
0
// own requests ownership over the role of window manager in the current
// X environment. It can fail if it does not successfully get ownership.
//
// When 'replace' is true, Wingo will attempt to replace an window manager
// that is currently running. Otherwise, Wingo will quit if a window manager
// is running.
func own(X *xgbutil.XUtil, replace bool) error {
	otherWmRunning := false
	otherWmName := ""
	otherWmOwner := xproto.Window(xproto.WindowNone)

	xTime, err := currentTime(X)
	if err != nil {
		return err
	}

	selAtom, err := managerAtom(X)
	if err != nil {
		return err
	}

	// Check to see if we need to replace. If so, determine whether to
	// continue based on `replace`.
	reply, err := xproto.GetSelectionOwner(X.Conn(), selAtom).Reply()
	if err != nil {
		return err
	}
	if reply.Owner != xproto.WindowNone {
		otherWmRunning = true
		otherWmOwner = reply.Owner

		// Look for the window manager's name for a nicer error message.
		otherWmName, err = ewmh.GetEwmhWM(X)
		if err != nil || len(otherWmName) == 0 {
			otherWmName = "Unknown"
		}

		// We need to listen for DestroyNotify events on the selection
		// owner in case we need to replace the WM.
		owner := xwindow.New(X, reply.Owner)
		if err = owner.Listen(xproto.EventMaskStructureNotify); err != nil {
			return err
		}
	}
	if otherWmRunning {
		if !replace {
			return fmt.Errorf(
				"Another window manager (%s) is already running. Please use "+
					"the '--replace' option to replace the current window "+
					"manager with Wingo.", otherWmName)
		} else {
			logger.Message.Printf(
				"Waiting for %s to shutdown and transfer ownership to us.",
				otherWmName)
		}
	}

	logger.Message.Printf("Setting selection owner...")
	err = xproto.SetSelectionOwnerChecked(
		X.Conn(), X.Dummy(), selAtom, xTime).Check()
	if err != nil {
		return err
	}

	// Now we've got to make sure that we *actually* got ownership.
	logger.Message.Printf("Getting selection owner...")
	reply, err = xproto.GetSelectionOwner(X.Conn(), selAtom).Reply()
	if err != nil {
		return err
	}
	if reply.Owner != X.Dummy() {
		return fmt.Errorf(
			"Could not acquire ownership with SetSelectionOwner. "+
				"GetSelectionOwner claims that '%d' is the owner, but '%d' "+
				"needs to be.", reply.Owner, X.Dummy())
	}

	// While X now acknowledges us as the selection owner, it's possible
	// that the window manager is misbehaving. ICCCM 2.8 calls for the previous
	// manager to destroy the selection owner when it's OK for us to take
	// over. Otherwise, listening to SubstructureRedirect on the root window
	// might fail if we move too quickly.
	timeout := time.After(3 * time.Second)
	if otherWmRunning {
	OTHER_WM_SHUTDOWN:
		for {
			select {
			case <-timeout:
				return fmt.Errorf(
					"Wingo failed to replace the currently running window "+
						"manager (%s). Namely, Wingo was not able to detect "+
						"that the current window manager had shut down.",
					otherWmName)
			default:
				logger.Message.Printf("Polling for event...")
				ev, err := X.Conn().PollForEvent()
				if err != nil {
					continue
				}
				logger.Message.Printf("Got event, error: %s -- %s", ev, err)
				if destNotify, ok := ev.(xproto.DestroyNotifyEvent); ok {
					if destNotify.Window == otherWmOwner {
						break OTHER_WM_SHUTDOWN
					}
				}
				time.Sleep(100 * time.Millisecond)
			}
		}
	}

	logger.Message.Println("Wingo has window manager ownership!")
	announce(X)

	// Listen for SelectionClear events. When we get one of these, then we
	// know a window manager is trying to replace us.
	xevent.SelectionClearFun(disown).Connect(X, X.Dummy())
	return nil
}
Пример #4
0
func main() {
	X, Xerr = xgbutil.NewConn()
	if Xerr != nil {
		panic(Xerr)
	}

	active, _ := ewmh.ActiveWindowGet(X)

	parent, _ := xwindow.ParentWindow(X, active)
	actOpacity, _ := ewmh.WmWindowOpacityGet(X, parent)
	fmt.Printf("Opacity for active window: %f\n", actOpacity)

	showDesk, _ := ewmh.ShowingDesktopGet(X)
	fmt.Printf("Showing desktop? %v\n", showDesk)

	wmName, err := ewmh.GetEwmhWM(X)
	if err != nil {
		fmt.Printf("No conforming window manager found... :-(\n")
		fmt.Println(err)
	} else {
		fmt.Printf("Window manager: %s\n", wmName)
	}

	pager := xproto.Window(0x160001e)
	middle := xproto.Window(0x3200016)
	geom, _ := ewmh.DesktopGeometryGet(X)
	desktops, _ := ewmh.DesktopNamesGet(X)
	curdesk, _ := ewmh.CurrentDesktopGet(X)
	clients, _ := ewmh.ClientListGet(X)
	activeName, _ := ewmh.WmNameGet(X, active)

	fmt.Printf("Active window: %x\n", active)
	fmt.Printf("Current desktop: %d\n", curdesk)
	fmt.Printf("Client list: %v\n", clients)
	fmt.Printf("Desktop geometry: (width: %d, height: %d)\n",
		geom.Width, geom.Height)
	fmt.Printf("Active window name: %s\n", activeName)
	fmt.Printf("Desktop names: %s\n", desktops)

	var desk string
	if curdesk < len(desktops) {
		desk = desktops[curdesk]
	} else {
		desk = string(curdesk)
	}
	fmt.Printf("Current desktop: %s\n", desk)

	// fmt.Printf("\nChanging current desktop to 25 from %d\n", curdesk)
	ewmh.CurrentDesktopSet(X, curdesk)
	// fmt.Printf("Current desktop is now: %d\n", ewmh.CurrentDesktop(X))

	fmt.Printf("Setting active win to %x\n", middle)
	// ewmh.ActiveWindowReq(X, middle)

	rand.Seed(int64(time.Now().Nanosecond()))
	randStr := make([]byte, 20)
	for i, _ := range randStr {
		if rf := rand.Float32(); rf < 0.40 {
			randStr[i] = byte('a' + rand.Intn('z'-'a'))
		} else if rf < 0.80 {
			randStr[i] = byte('A' + rand.Intn('Z'-'A'))
		} else {
			randStr[i] = ' '
		}
	}

	ewmh.WmNameSet(X, active, string(randStr))
	newName, _ := ewmh.WmNameGet(X, active)
	fmt.Printf("New name: %s\n", newName)

	// deskNames := ewmh.DesktopNamesGet(X)
	// fmt.Printf("Desktop names: %s\n", deskNames)
	// deskNames[len(deskNames) - 1] = "xgbutil"
	// ewmh.DesktopNamesSet(X, deskNames)
	// fmt.Printf("Desktop names: %s\n", ewmh.DesktopNamesGet(X))

	supported, _ := ewmh.SupportedGet(X)
	fmt.Printf("Supported hints: %v\n", supported)
	fmt.Printf("Setting supported hints...\n")
	ewmh.SupportedSet(X, []string{"_NET_CLIENT_LIST", "_NET_WM_NAME",
		"_NET_WM_DESKTOP"})

	numDesks, _ := ewmh.NumberOfDesktopsGet(X)
	fmt.Printf("Number of desktops: %d\n", numDesks)
	// ewmh.NumberOfDesktopsReq(X.EwmhNumberOfDesktops(X) + 1)
	// time.Sleep(time.Second)
	// fmt.Printf("Number of desktops: %d\n", ewmh.NumberOfDesktops(X))

	viewports, _ := ewmh.DesktopViewportGet(X)
	fmt.Printf("Viewports (%d): %v\n", len(viewports), viewports)

	// viewports[2].X = 50
	// viewports[2].Y = 293
	// ewmh.DesktopViewportSet(X, viewports)
	// time.Sleep(time.Second)
	//
	// viewports = ewmh.DesktopViewport(X)
	// fmt.Printf("Viewports (%d): %v\n", len(viewports), viewports)

	// ewmh.CurrentDesktopReq(X, 3)

	visDesks, _ := ewmh.VisibleDesktopsGet(X)
	workarea, _ := ewmh.WorkareaGet(X)
	fmt.Printf("Visible desktops: %v\n", visDesks)
	fmt.Printf("Workareas: %v\n", workarea)
	// fmt.Printf("Virtual roots: %v\n", ewmh.VirtualRoots(X))
	// fmt.Printf("Desktop layout: %v\n", ewmh.DesktopLayout(X))
	fmt.Printf("Closing window %x\n", 0x2e004c5)
	ewmh.CloseWindow(X, 0x1e00cdf)

	fmt.Printf("Moving/resizing window: %x\n", 0x2e004d0)
	ewmh.MoveresizeWindow(X, 0x2e004d0, 1920, 30, 500, 500)

	// fmt.Printf("Trying to initiate a moveresize...\n")
	// ewmh.WmMoveresize(X, 0x2e004db, xgbutil.EwmhMove)
	// time.Sleep(5 * time.Second)
	// ewmh.WmMoveresize(X, 0x2e004db, xgbutil.EwmhCancel)

	// fmt.Printf("Stacking window %x...\n", 0x2e00509)
	// ewmh.RestackWindow(X, 0x2e00509)

	fmt.Printf("Requesting frame extents for active window...\n")
	ewmh.RequestFrameExtents(X, active)

	activeDesk, _ := ewmh.WmDesktopGet(X, active)
	activeType, _ := ewmh.WmWindowTypeGet(X, active)
	fmt.Printf("Active window's desktop: %d\n", activeDesk)
	fmt.Printf("Active's types: %v\n", activeType)
	// fmt.Printf("Pager's types: %v\n", ewmh.WmWindowType(X, 0x180001e))

	// fmt.Printf("Pager's state: %v\n", ewmh.WmState(X, 0x180001e))

	// ewmh.WmStateReq(X, active, xgbutil.EwmhStateToggle,
	// "_NET_WM_STATE_HIDDEN")
	// ewmh.WmStateReqExtra(X, active, xgbutil.EwmhStateToggle,
	// "_NET_WM_STATE_MAXIMIZED_VERT",
	// "_NET_WM_STATE_MAXIMIZED_HORZ", 2)

	activeAllowed, _ := ewmh.WmAllowedActionsGet(X, active)
	fmt.Printf("Allowed actions on active: %v\n", activeAllowed)

	struts, err := ewmh.WmStrutGet(X, pager)
	if err != nil {
		fmt.Printf("Pager struts: %v\n", err)
	} else {
		fmt.Printf("Pager struts: %v\n", struts)
	}

	pstruts, err := ewmh.WmStrutPartialGet(X, pager)
	if err != nil {
		fmt.Printf("Pager struts partial: %v - %v\n", pstruts, err)
	} else {
		fmt.Printf("Pager struts partial: %v\n", pstruts.BottomStartX)
	}

	// fmt.Printf("Icon geometry for active: %v\n",
	// ewmh.WmIconGeometry(X, active))

	icons, _ := ewmh.WmIconGet(X, active)
	fmt.Printf("Active window's (%x) icon data: (length: %v)\n",
		active, len(icons))
	for _, icon := range icons {
		fmt.Printf("\t(%d, %d)", icon.Width, icon.Height)
		fmt.Printf(" :: %d == %d\n", icon.Width*icon.Height, len(icon.Data))
	}
	// fmt.Printf("Now set them again...\n")
	// ewmh.WmIconSet(X, active, icons[:len(icons) - 1])
}
Пример #5
0
func main() {

	// I don't want to retype all of these things
	// TODO: find/replace fatal with util.Fatal
	fatal := util.Fatal

	// establish X connection
	X, err := xgbutil.NewConn()
	fatal(err)

	// initiate extension tools
	shape.Init(X.Conn())
	mousebind.Initialize(X)

	// Detail our current window manager. Insures a minimum of EWMH compliance
	wm_name, err := ewmh.GetEwmhWM(X)
	fatal(err)
	log.Printf("Window manager: %s\n", wm_name)

	// create the cross UI
	cross_ui := makeCross(X)
	cross := cross_ui.Window

	// map the icons on the cross the the actions they should perform
	// when objects are dropped over them
	win_to_action := make(map[xproto.Window]wm.WindowInteraction)
	for name, icon := range cross_ui.Icons {
		if action, ok := wm.Actions[name]; ok {
			win_to_action[icon.Window.Id] = action
		} else {
			// otherwise,
			// shade the icon because it has no action attatched to it
			icon.SetState(ui.StateDisabled)
		}
	}

	// define handlers for the three parts of any drag-drop operation
	dm := util.DragManager{}
	handleDragStart := func(X *xgbutil.XUtil, rx, ry, ex, ey int) (cont bool, cursor xproto.Cursor) {
		// find the window we are trying to drag
		win, err := wm.FindManagedWindowUnderMouse(X)
		if err != nil {
			// don't continue the drag
			log.Printf("DragStart: could not get incoming window: %v\n", err)
			return false, 0
		}

		// cool awesome!
		dm.StartDrag(win)
		// continue the drag
		return true, 0
	}

	handleDragStep := func(X *xgbutil.XUtil, rx, ry, ex, ey int) {
		// see if we have a window that ISN'T the incoming window
		win, err := wm.FindManagedWindowUnderMouse(X)
		if err != nil {
			// whatever
			log.Printf("DragStep: no window found or something: %v\n", err)
			return
		}

		// oh we have a window? and it isn't the start window!? And not the current target!?
		if win != dm.Incoming && win != dm.Target {
			// reposition the cross over it
			// TODO: actually do this, center operates on rects, and all I have is this xproto.Window
			dm.SetTarget(win)

			// get the target width/height
			target_geom, err := xwindow.New(X, win).Geometry()
			if err != nil {
				log.Printf("DragStep: issues getting target geometry: %v\n", err)
				return
			}

			// set the target goemetry X, Y to the actual x, y relative to the root window
			tx, ty, err := wm.TranslateCoordinatesSync(X, win, X.RootWin(), 0, 0)
			if err != nil {
				log.Printf("DragStep: issue translating target coordinates to root coordinates: %v\n", err)
				return
			}
			target_geom.XSet(tx)
			target_geom.YSet(ty)
			x, y := util.CenterOver(cross.Geom, target_geom)
			cross.Move(x, y)
			cross.Map()
		}
	}

	handleDragEnd := func(X *xgbutil.XUtil, rx, ry, ex, ey int) {
		exit_early := false
		// get icon we are dropping over
		icon_win, _, err := wm.FindNextUnderMouse(X, cross.Id)
		if err != nil {
			log.Printf("DragEnd: icon not found: %v\n", err)
			exit_early = true
		}

		incoming, target, err := dm.EndDrag()
		// drag manager produces errors if we don't have both an Incoming and a Target yet
		if err != nil {
			log.Printf("DragEnd: drag manager state error: %v\n", err)
			exit_early = true
		}

		// we tried: hide UI
		cross.Unmap()

		// we had some sort of error, escape!
		if exit_early {
			return
		}

		// retrieve the action that this icon indicates
		if action, ok := win_to_action[icon_win]; ok {
			// create util-window objects from our window IDs
			if incoming_id, inc_ok := incoming.(xproto.Window); inc_ok {
				inc_win := xwindow.New(X, incoming_id)
				if target_id, t_ok := target.(xproto.Window); t_ok {
					t_win := xwindow.New(X, target_id)

					// perform the action!
					action(t_win, inc_win)

				} else {
					log.Println("DragEnd: target type error (was %v)\n", target)
				}
			} else {
				log.Println("DragEnd: incoming type error (was %v)\n", incoming)
			}
		} else {
			log.Printf("DragEnd: couldn't map window %v to an action", icon_win)
		}
	}

	mousebind.Drag(X, X.RootWin(), X.RootWin(), KeyComboMove, true,
		handleDragStart,
		handleDragStep,
		handleDragEnd)

	///////////////////////////////////////////////////////////////////////////
	// Window resizing behavior spike
	ManageResizingWindows(X)

	// start event loop, even though we have no events
	// to keep app from just closing
	xevent.Main(X)
}