// newClientFrames constructs a clientFrames value, initializes all possible // frames for this client, and sets up and activates the initial frame. func (c *Client) newClientFrames() clientFrames { // When reparenting, an UnmapNotify is generated. We must ignore it! c.unmapIgnore++ cf := createFrames(c) if c.shouldDecor() { c.frame = cf.full } else { if c.PrimaryType() == TypeNormal { if c.shaped { c.frame = cf.nada } else { c.frame = cf.slim } } else { c.frame = cf.nada } } x, y, w, h := frame.ClientToFrame(c.frame, -1, c.win.Geom.X(), c.win.Geom.Y(), c.win.Geom.Width(), c.win.Geom.Height()) x, y = max(0, x), max(0, y) c.frame.MoveResize(true, x, y, w, h) c.frame.On() c.refreshExtents() return cf }
func (c *Client) cbConfigureRequest() xevent.ConfigureRequestFun { f := func(X *xgbutil.XUtil, ev xevent.ConfigureRequestEvent) { if c.frame.Moving() || c.frame.Resizing() || c.maximized || c.fullscreen { logger.Lots.Printf("Denying ConfigureRequest from client because " + "the client is in the processing of moving/resizing, or is " + "maximized/fullscreen.") // As per ICCCM 4.1.5, a window that has not been moved or resized // must receive a synthetic ConfigureNotify event. c.sendConfigureNotify() return } if _, ok := c.Layout().(layout.Floater); !ok { logger.Lots.Printf("Denying ConfigureRequest from client because " + "the client is not in a floating layout.") // As per ICCCM 4.1.5, a window that has not been moved or resized // must receive a synthetic ConfigureNotify event. c.sendConfigureNotify() return } flags := int(ev.ValueMask) & ^int(xproto.ConfigWindowStackMode) & ^int(xproto.ConfigWindowSibling) x, y, w, h := frame.ClientToFrame(c.frame, -1, int(ev.X), int(ev.Y), int(ev.Width), int(ev.Height)) c.LayoutMROpt(flags, x, y, w, h) } return xevent.ConfigureRequestFun(f) }
func (c *Client) handleClientMessage(name string, data []uint32) { switch name { case "WM_CHANGE_STATE": if data[0] == icccm.StateIconic && !c.iconified { c.IconifyToggle() } case "_NET_ACTIVE_WINDOW": c.Focus() c.Raise() case "_NET_CLOSE_WINDOW": c.Close() case "_NET_MOVERESIZE_WINDOW": // The data[0] element contains bit-packed information. See // EWMH _NET_MOVERESIZE_WINDOW for the deets. gravity := int(data[0] & 0xff) xflags := int((data[0] >> 8) & 0xf) x, y, w, h := frame.ClientToFrame(c.frame, gravity, int(data[1]), int(data[2]), int(data[3]), int(data[4])) c.LayoutMROpt(xflags, x, y, w, h) case "_NET_RESTACK_WINDOW": // We basically treat this as a request to stack the window. // We ignore the sibling. Maybe someday we can support that, but eh... c.Raise() case "_NET_WM_DESKTOP": if data[0] == 0xFFFFFFFF { c.stick() return } if wrk := wm.Heads.Workspaces.Get(int(data[0])); wrk != nil { wrk.Add(c) } else { logger.Warning.Printf( "_NET_WM_DESKTOP ClientMessage: No workspace indexed at '%d' "+ "exists.", data[0]) } case "_NET_WM_STATE": prop1, _ := xprop.AtomName(wm.X, xproto.Atom(data[1])) prop2, _ := xprop.AtomName(wm.X, xproto.Atom(data[2])) switch data[0] { case 0: c.updateStates("remove", prop1, prop2) case 1: c.updateStates("add", prop1, prop2) case 2: c.updateStates("toggle", prop1, prop2) default: logger.Warning.Printf( "_NET_WM_STATE: Unknown action '%d'.", data[0]) } default: logger.Warning.Printf("Unknown ClientMessage for '%s': %s.", c, name) } }