func initShape() { initShapeOnce.Do(func() { shape.Init(XU.Conn()) }) }
func Initialize(x *xgbutil.XUtil, cmdEnv *gribble.Environment, hacks CommandHacks, configDir string) { var err error X = x Startup = true ConfigDir = configDir gribbleEnv = cmdEnv cmdHacks = hacks Root = xwindow.New(X, X.RootWin()) if _, err = Root.Geometry(); err != nil { logger.Error.Fatalf("Could not get ROOT window geometry: %s", err) } if Config, err = loadConfig(); err != nil { logger.Error.Fatalf("Could not load configuration: %s", err) } if Theme, err = loadTheme(); err != nil { logger.Error.Fatalf("Could not load theme: %s", err) } Clients = make(ClientList, 0, 50) Prompts = newPrompts() Heads = heads.NewHeads(X, Config.DefaultLayout) // If _NET_DESKTOP_NAMES is set, let's use workspaces from that instead. if names, _ := ewmh.DesktopNamesGet(X); len(names) > 0 { for _, wrkName := range names { if err := AddWorkspace(wrkName); err != nil { logger.Warning.Printf("Could not add workspace %s: %s", wrkName, err) } } } else { for _, wrkName := range Config.Workspaces { if err := AddWorkspace(wrkName); err != nil { logger.Error.Fatalf("Could not initialize workspaces: %s", err) } } } Heads.Initialize(Clients) keybindings() rootMouseSetup() StickyWrk = Heads.Workspaces.NewSticky() err = shape.Init(X.Conn()) if err != nil { ShapeExt = false logger.Warning.Printf("The X SHAPE extension could not be loaded. " + "Google Chrome might look ugly.") } else { ShapeExt = true } Restart = false ewmhClientList() ewmhNumberOfDesktops() ewmhCurrentDesktop() ewmhVisibleDesktops() ewmhDesktopNames() ewmhDesktopGeometry() }
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) }