func (cmd GetLayout) Run() gribble.Value { return syncRun(func() gribble.Value { var w workspace.Workspacer = nil withWorkspace(cmd.Workspace, func(wrk *workspace.Workspace) { w = wrk }) if w == nil { return "" } return w.LayoutName() }) }
func (cmd GetClientWorkspace) Run() gribble.Value { return syncRun(func() gribble.Value { var wrk workspace.Workspacer = nil withClient(cmd.Client, func(c *xclient.Client) { wrk = c.Workspace() }) if wrk == nil { return "" } return wrk.String() }) }
// moveToProperHead is used to make sure a newly managed client is placed on // the correct monitor. // // Before adding the client into our data structures, we should first // make sure it's located on the right head. We do this by finding where // it *is* placed and convert it into the coordinate space of where it // *should* be placed. // // Note that presumedWorkspace MUST be visible. func (c *Client) moveToProperHead(presumedWorkspace workspace.Workspacer) { if c.PrimaryType() != TypeNormal { return } if _, ok := presumedWorkspace.(*workspace.Sticky); ok { return } if !presumedWorkspace.IsVisible() { return } oughtHeadGeom := presumedWorkspace.HeadGeom() cgeom := c.frame.Geom() if wrk := wm.Heads.FindMostOverlap(cgeom); wrk != nil { if wrk != presumedWorkspace { isHeadGeom := wrk.HeadGeom() ngeom := heads.Convert(cgeom, isHeadGeom, oughtHeadGeom) c.MoveResizeValid( ngeom.X(), ngeom.Y(), ngeom.Width(), ngeom.Height()) } } else { // If we're here, that means the client *ought* to belong to a visible // workspace but it could not be found to overlap with *any* visible // workspace. Therefore, just use a hammer and move it to the root // coordinates of the presumed workspace. geom := presumedWorkspace.Geom() c.Move(geom.X(), geom.Y()) } }
func (c *Client) maybeInitPlace(presumedWorkspace workspace.Workspacer) { // This is a hack. Before a client gets sucked into some layout, we // always want to have some floating state to fall back on to. However, // by the time we're "allowed" to save the client's state, it will have // already been placed in the hands of some layout---which may or may // not be floating. So we inject our own state forcefully here. defer func() { wrk := presumedWorkspace if wrk.IsVisible() { c.states["last-floating"] = clientState{ geom: xrect.New(xrect.Pieces(c.frame.Geom())), headGeom: xrect.New(xrect.Pieces(wrk.HeadGeom())), frame: c.frame, maximized: c.maximized, } } else if wm.Startup { // This is a bit tricky. If the window manager is starting up and // has to manage existing clients, then we need to find which // head the client is on and save its state. This is so future // workspace switches will be able to place the client // appropriately. // (This is most common on a Wingo restart.) // We refer to detected workspace as "fake" because the client // isn't on a visible workspace (see above), and therefore the // visible workspace returned by FindMostOverlap *cannot* contain // this client. Therefore, we're only using the fake workspace // to get the geometry. // (This would make more sense if FindMostOverlap returned a head // geometry, but it turns out that a workspace geometry is more // useful.) cgeom := c.frame.Geom() if fakeWrk := wm.Heads.FindMostOverlap(cgeom); fakeWrk != nil { c.states["last-floating"] = clientState{ geom: xrect.New(xrect.Pieces(c.frame.Geom())), headGeom: xrect.New(xrect.Pieces(fakeWrk.HeadGeom())), frame: c.frame, maximized: c.maximized, } } } }() // Any client that isn't normal doesn't get placed. // Let it do what it do, baby. if c.PrimaryType() != TypeNormal { return } // If it's sticky, let it do what it do. if _, ok := presumedWorkspace.(*workspace.Sticky); ok { return } // Transients never get placed. if c.transientFor != nil { return } // If a user/program position is specified, do not place. if c.nhints.Flags&icccm.SizeHintUSPosition > 0 || c.nhints.Flags&icccm.SizeHintPPosition > 0 { return } // We're good, do a placement unless we're already mapped or on a // hidden workspace.. if !presumedWorkspace.IsVisible() || !c.isAttrsUnmapped() { return } w := presumedWorkspace.(*workspace.Workspace) w.LayoutFloater().InitialPlacement(c) }