Example #1
0
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)
	}
}
Example #2
0
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)
			}
		})
	})
}
Example #3
0
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
	})
}
Example #4
0
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
	})
}
Example #5
0
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
	})
}
Example #6
0
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
	})
}
Example #7
0
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()
		}
	}
}
Example #8
0
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()
	}
}
Example #9
0
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)
	}
}