func (s *screenImpl) run() { for { ev, err := s.xc.WaitForEvent() if err != nil { log.Printf("x11driver: xproto.WaitForEvent: %v", err) continue } noWindowFound := false switch ev := ev.(type) { case xproto.DestroyNotifyEvent: s.mu.Lock() delete(s.windows, ev.Window) s.mu.Unlock() case shm.CompletionEvent: s.mu.Lock() s.completionKeys = append(s.completionKeys, ev.Sequence) s.handleCompletions() s.mu.Unlock() case xproto.ClientMessageEvent: if ev.Type != s.atomWMProtocols || ev.Format != 32 { break } switch xproto.Atom(ev.Data.Data32[0]) { case s.atomWMDeleteWindow: // TODO. case s.atomWMTakeFocus: xproto.SetInputFocus(s.xc, xproto.InputFocusParent, ev.Window, xproto.Timestamp(ev.Data.Data32[1])) } case xproto.ConfigureNotifyEvent: if w := s.findWindow(ev.Window); w != nil { w.handleConfigureNotify(ev) } else { noWindowFound = true } case xproto.ExposeEvent: if w := s.findWindow(ev.Window); w != nil { // A non-zero Count means that there are more expose events // coming. For example, a non-rectangular exposure (e.g. from a // partially overlapped window) will result in multiple expose // events whose dirty rectangles combine to define the dirty // region. Go's paint events do not provide dirty regions, so // we only pass on the final X11 expose event. if ev.Count == 0 { w.handleExpose() } } else { noWindowFound = true } case xproto.FocusInEvent: // TODO: xw = ev.Event case xproto.FocusOutEvent: // TODO: xw = ev.Event case xproto.KeyPressEvent: if w := s.findWindow(ev.Event); w != nil { w.handleKey(ev.Detail, ev.State, key.DirPress) } else { noWindowFound = true } case xproto.KeyReleaseEvent: if w := s.findWindow(ev.Event); w != nil { w.handleKey(ev.Detail, ev.State, key.DirRelease) } else { noWindowFound = true } case xproto.ButtonPressEvent: if w := s.findWindow(ev.Event); w != nil { w.handleMouse(ev.EventX, ev.EventY, ev.Detail, ev.State, mouse.DirPress) } else { noWindowFound = true } case xproto.ButtonReleaseEvent: if w := s.findWindow(ev.Event); w != nil { w.handleMouse(ev.EventX, ev.EventY, ev.Detail, ev.State, mouse.DirRelease) } else { noWindowFound = true } case xproto.MotionNotifyEvent: if w := s.findWindow(ev.Event); w != nil { w.handleMouse(ev.EventX, ev.EventY, 0, ev.State, mouse.DirNone) } else { noWindowFound = true } } if noWindowFound { log.Printf("x11driver: no window found for event %T", ev) } } }
// FocusParent is just like Focus, except it sets the "revert-to" mode to // Parent. This should be used when setting focus to a sub-window. func (w *Window) FocusParent(tstamp xproto.Timestamp) { xproto.SetInputFocus(w.X.Conn(), xproto.InputFocusParent, w.Id, tstamp) }
func (s *screenImpl) run() { for { ev, err := s.xc.WaitForEvent() if err != nil { log.Printf("x11driver: xproto.WaitForEvent: %v", err) continue } noWindowFound := false switch ev := ev.(type) { case xproto.DestroyNotifyEvent: s.mu.Lock() delete(s.windows, ev.Window) s.mu.Unlock() case shm.CompletionEvent: s.handleCompletion(ev) case xproto.ClientMessageEvent: if ev.Type != s.atomWMProtocols || ev.Format != 32 { break } switch xproto.Atom(ev.Data.Data32[0]) { case s.atomWMDeleteWindow: // TODO. case s.atomWMTakeFocus: xproto.SetInputFocus(s.xc, xproto.InputFocusParent, ev.Window, xproto.Timestamp(ev.Data.Data32[1])) } case xproto.ConfigureNotifyEvent: if w := s.findWindow(ev.Window); w != nil { w.handleConfigureNotify(ev) } else { noWindowFound = true } case xproto.ExposeEvent: // TODO: xw = ev.Window case xproto.FocusInEvent: // TODO: xw = ev.Event case xproto.FocusOutEvent: // TODO: xw = ev.Event case xproto.KeyPressEvent: // TODO: xw = ev.Event case xproto.KeyReleaseEvent: // TODO: xw = ev.Event case xproto.ButtonPressEvent: if w := s.findWindow(ev.Event); w != nil { w.handleMouse(ev.EventX, ev.EventY, ev.Detail, ev.State, mouse.DirPress) } else { noWindowFound = true } case xproto.ButtonReleaseEvent: if w := s.findWindow(ev.Event); w != nil { w.handleMouse(ev.EventX, ev.EventY, ev.Detail, ev.State, mouse.DirRelease) } else { noWindowFound = true } case xproto.MotionNotifyEvent: if w := s.findWindow(ev.Event); w != nil { w.handleMouse(ev.EventX, ev.EventY, 0, ev.State, mouse.DirNone) } else { noWindowFound = true } } if noWindowFound { log.Printf("x11driver: no window found for event %T", ev) } } }
// Focus tries to issue a SetInputFocus to get the focus. // If you're trying to change the top-level active window, please use // ewmh.ActiveWindowReq instead. func (w *Window) Focus() { xproto.SetInputFocus(w.X.Conn(), xproto.InputFocusPointerRoot, w.Id, 0) }