func()

in shiny/driver/x11driver/screen.go [117:246]


func (s *screenImpl) run() {
	keyboardChanged := false
	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:
				if w := s.findWindow(ev.Window); w != nil {
					w.lifecycler.SetDead(true)
					w.lifecycler.SendEvent(w, nil)
				} else {
					noWindowFound = true
				}
			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:
			if w := s.findWindow(ev.Event); w != nil {
				w.lifecycler.SetFocused(true)
				w.lifecycler.SendEvent(w, nil)
			} else {
				noWindowFound = true
			}

		case xproto.FocusOutEvent:
			if w := s.findWindow(ev.Event); w != nil {
				w.lifecycler.SetFocused(false)
				w.lifecycler.SendEvent(w, nil)
			} else {
				noWindowFound = true
			}

		case xproto.KeyPressEvent:
			if keyboardChanged {
				keyboardChanged = false
				s.initKeyboardMapping()
			}
			if w := s.findWindow(ev.Event); w != nil {
				w.handleKey(ev.Detail, ev.State, key.DirPress)
			} else {
				noWindowFound = true
			}

		case xproto.KeyReleaseEvent:
			if keyboardChanged {
				keyboardChanged = false
				s.initKeyboardMapping()
			}
			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
			}

		case xproto.MappingNotifyEvent:
			if ev.Request == xproto.MappingModifier || ev.Request == xproto.MappingKeyboard {
				keyboardChanged = true
			}
		}

		if noWindowFound {
			log.Printf("x11driver: no window found for event %T", ev)
		}
	}
}