func (c *Client) cbUnmapNotify() xevent.UnmapNotifyFun { f := func(X *xgbutil.XUtil, ev xevent.UnmapNotifyEvent) { // When a client issues an Unmap request, the window manager should // unmanage it. However, when wingo unmaps the window, we shouldn't // unmanage it. Thus, every time wingo unmaps the window, the // unmapIgnore counter is incremented. Only when it is zero does it mean // that we should unmanage the client (i.e., the unmap request came // from somewhere other than Wingo.) if c.unmapIgnore > 0 { c.unmapIgnore-- return } c.unmanage() } return xevent.UnmapNotifyFun(f) }
func (c *client) cbUnmapNotify() xevent.UnmapNotifyFun { f := func(X *xgbutil.XUtil, ev xevent.UnmapNotifyEvent) { // If a client has "iconified" set to true and we get an UnmapNotify // event, then that means we need to switch focus to the next window // in the focus stack. if c.iconified && focus.Current().Id() == c.Id() { wingo.focusFallback() } // When a client issues an Unmap request, the window manager should // unmanage it. However, when wingo unmaps the window, we shouldn't // unmanage it. Thus, every time wingo unmaps the window, the // unmapIgnore counter is incremented. Only when it is zero does it mean // that we should unmanage the client (i.e., the unmap request came // from somewhere other than Wingo.) if c.unmapIgnore > 0 { c.unmapIgnore-- return } c.unmanage() } return xevent.UnmapNotifyFun(f) }
func (app *RuntimeApp) attachXid(xid xproto.Window) { logger.Debugf("attach 0x%x to %s", xid, app.Id) if _, ok := app.xids[xid]; ok { logger.Debugf("0x%x is already on %s", xid, app.Id) return } xwin := xwindow.New(XU, xid) xwin.Listen(xproto.EventMaskPropertyChange | xproto.EventMaskStructureNotify | xproto.EventMaskVisibilityChange) winfo := &WindowInfo{Xid: xid} xevent.UnmapNotifyFun(func(XU *xgbutil.XUtil, ev xevent.UnmapNotifyEvent) { app.detachXid(xid) }).Connect(XU, xid) xevent.DestroyNotifyFun(func(XU *xgbutil.XUtil, ev xevent.DestroyNotifyEvent) { app.detachXid(xid) }).Connect(XU, xid) xevent.PropertyNotifyFun(func(XU *xgbutil.XUtil, ev xevent.PropertyNotifyEvent) { app.lock.Lock() defer app.lock.Unlock() switch ev.Atom { case ATOM_WINDOW_ICON: app.updateIcon(xid) app.updateAppid(xid) app.notifyChanged() case ATOM_WINDOW_NAME: if app.updateWMNameTimer != nil { app.updateWMNameTimer.Stop() app.updateWMNameTimer = nil } app.updateWMNameTimer = time.AfterFunc(time.Millisecond*20, func() { app.updateWmName(xid) app.updateAppid(xid) app.notifyChanged() app.updateWMNameTimer = nil }) case ATOM_WINDOW_STATE: logger.Debugf("%s(0x%x) WM_STATE is changed", app.Id, xid) if app.CurrentInfo.Xid == xid { logger.Debug("is current window info changed") app.updateState(xid) } app.notifyChanged() if HideModeType(setting.GetHideMode()) != HideModeSmartHide { break } time.AfterFunc(time.Millisecond*20, func() { app.updateOverlap(xid) }) // case ATOM_DEEPIN_WINDOW_VIEWPORTS: // app.updateViewports(xid) case ATOM_WINDOW_TYPE: if !isNormalWindow(ev.Window) { app.detachXid(xid) } case ATOM_DOCK_APP_ID: app.updateAppid(xid) app.notifyChanged() } }).Connect(XU, xid) update := func(xid xproto.Window) { app.lock.Lock() defer app.lock.Unlock() app.updateOverlap(xid) } xevent.ConfigureNotifyFun(func(XU *xgbutil.XUtil, ev xevent.ConfigureNotifyEvent) { app.lock.Lock() defer app.lock.Unlock() if app.updateConfigureTimer != nil { app.updateConfigureTimer.Stop() app.updateConfigureTimer = nil } app.updateConfigureTimer = time.AfterFunc(time.Millisecond*20, func() { update(ev.Window) app.updateConfigureTimer = nil }) }).Connect(XU, xid) app.xids[xid] = winfo update(xid) app.updateIcon(xid) app.updateWmName(xid) app.updateState(xid) // app.updateViewports(xid) app.notifyChanged() }