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) }
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) } }
// 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 }
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]) }
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) }