func handleClientMessages(X *xgbutil.XUtil, ev xevent.ClientMessageEvent) { name, err := xprop.AtomName(X, ev.Type) if err != nil { logger.Warning.Printf("Could not get atom name for '%s': %s", ev, err) return } switch name { case "_NET_NUMBER_OF_DESKTOPS": logger.Warning.Printf("Wingo does not support adding/removing " + "desktops using the _NET_NUMBER_OF_DESKTOPS property. Please use " + "the Wingo commands 'AddWorkspace' and 'RemoveWorkspace' to add " + "or remove workspaces.") case "_NET_DESKTOP_GEOMETRY": logger.Warning.Printf("Wingo does not support the " + "_NET_DESKTOP_GEOMETRY property. Namely, more than one workspace " + "can be visible at a time, so different workspaces can have " + "different geometries.") case "_NET_DESKTOP_VIEWPORT": logger.Warning.Printf("Wingo does not use viewports, and therefore " + "does not support the _NET_DESKTOP_VIEWPORT property.") case "_NET_CURRENT_DESKTOP": index := int(ev.Data.Data32[0]) if wrk := wm.Heads.Workspaces.Get(index); wrk != nil { wm.SetWorkspace(wrk, false) wm.FocusFallback() } else { logger.Warning.Printf("Desktop index %d is not in the range "+ "[0, %d).", index, len(wm.Heads.Workspaces.Wrks)) } default: logger.Warning.Printf("Unknown root client message: %s", name) } }
func (cmd Focus) Run() gribble.Value { return syncRun(func() gribble.Value { return withClient(cmd.Client, func(c *xclient.Client) { if c == nil { focus.Root() // Use the mouse coordinates to find which workspace it was // clicked in. If a workspace can be found (i.e., no clicks in // dead areas), then activate it. xc, rw := wm.X.Conn(), wm.X.RootWin() qp, err := xproto.QueryPointer(xc, rw).Reply() if err != nil { logger.Warning.Printf("Could not query pointer: %s", err) return } geom := xrect.New(int(qp.RootX), int(qp.RootY), 1, 1) if wrk := wm.Heads.FindMostOverlap(geom); wrk != nil { wm.SetWorkspace(wrk, false) } } else { c.Focus() xevent.ReplayPointer(wm.X) } }) }) }
func (cmd WorkspaceGreedy) Run() gribble.Value { return syncRun(func() gribble.Value { withWorkspace(cmd.Workspace, func(wrk *workspace.Workspace) { wm.SetWorkspace(wrk, true) wm.FocusFallback() }) return nil }) }
func (cmd HeadFocus) Run() gribble.Value { return syncRun(func() gribble.Value { wm.Heads.WithVisibleWorkspace(cmd.Head, func(wrk *workspace.Workspace) { wm.SetWorkspace(wrk, false) }) wm.FocusFallback() return nil }) }
func (cmd HeadCycle) Run() gribble.Value { return syncRun(func() gribble.Value { cur := wm.Heads.VisibleIndex(wm.Workspace()) next := misc.Mod(cur+1, wm.Heads.NumHeads()) wm.Heads.WithVisibleWorkspace(next, func(wrk *workspace.Workspace) { wm.SetWorkspace(wrk, false) }) wm.FocusFallback() return nil }) }
func (cmd HeadFocusWithClient) Run() gribble.Value { return syncRun(func() gribble.Value { withClient(cmd.Client, func(c *xclient.Client) { wm.Heads.WithVisibleWorkspace(cmd.Head, func(wrk *workspace.Workspace) { wm.SetWorkspace(wrk, false) wrk.Add(c) c.Raise() }) }) return nil }) }
func (cmd WorkspaceGreedyWithClient) Run() gribble.Value { return syncRun(func() gribble.Value { withWorkspace(cmd.Workspace, func(wrk *workspace.Workspace) { withClient(cmd.Client, func(c *xclient.Client) { c.Raise() wrk.Add(c) wm.SetWorkspace(wrk, true) wm.FocusFallback() }) }) return nil }) }
func handleMotionNotify(X *xgbutil.XUtil, ev xevent.MotionNotifyEvent) { qp, err := xproto.QueryPointer(X.Conn(), X.RootWin()).Reply() if err != nil { logger.Warning.Printf("Could not query pointer: %s", err) return } geom := xrect.New(int(qp.RootX), int(qp.RootY), 1, 1) if wrk := wm.Heads.FindMostOverlap(geom); wrk != nil { if wrk != wm.Workspace() { wm.SetWorkspace(wrk, false) wm.FocusFallback() } } }
func (c *Client) PrepareForFocus() { // There are only two ways a *managed* client is not prepared for focus: // 1) It belongs to any workspace except for the active one. // 2) It is iconified. // It is possible to be both. Check for both and remedy the situation. // We must check for (1) before (2), since a window cannot toggle its // iconification status if its workspace is not the current workspace. if c.workspace != wm.Workspace() { // This isn't applicable if we're sticky. if wrk, ok := c.workspace.(*workspace.Workspace); ok { wm.SetWorkspace(wrk, false) } } if c.iconified { c.IconifyToggle() } }
func (c *Client) CheckNewWorkspace() { var newWrk *workspace.Workspace = nil curWrk := c.Workspace() if dragGeom := c.DragGeom(); dragGeom != nil { newWrk = wm.Heads.FindMostOverlap(dragGeom) } else { newWrk = wm.Heads.FindMostOverlap(c.frame.Geom()) } if newWrk == nil || curWrk == newWrk { return } newWrk.Add(c) // If this is the active window, switch to this workspace too. if c.IsActive() { wm.SetWorkspace(newWrk, false) } }