M app/os.go => app/os.go +2 -0
@@ 45,6 45,8 @@ type Config struct {
CustomRenderer bool
// Decorated reports whether window decorations are provided automatically.
Decorated bool
+ // Focused reports whether has the keyboard focus.
+ Focused bool
// decoHeight is the height of the fallback decoration for platforms such
// as Wayland that may need fallback client-side decorations.
decoHeight unit.Dp
M app/os_android.go => app/os_android.go +2 -1
@@ 593,7 593,8 @@ func Java_org_gioui_GioView_onBack(env *C.JNIEnv, class C.jclass, view C.jlong)
//export Java_org_gioui_GioView_onFocusChange
func Java_org_gioui_GioView_onFocusChange(env *C.JNIEnv, class C.jclass, view C.jlong, focus C.jboolean) {
w := cgo.Handle(view).Value().(*window)
- w.processEvent(key.FocusEvent{Focus: focus == C.JNI_TRUE})
+ w.config.Focused = focus == C.JNI_TRUE
+ w.processEvent(ConfigEvent{Config: w.config})
}
//export Java_org_gioui_GioView_onWindowInsets
M app/os_ios.go => app/os_ios.go +2 -1
@@ 211,7 211,8 @@ func onDestroy(h C.uintptr_t) {
//export onFocus
func onFocus(h C.uintptr_t, focus int) {
w := viewFor(h)
- w.ProcessEvent(key.FocusEvent{Focus: focus != 0})
+ w.config.Focused = focus != 0
+ w.ProcessEvent(ConfigEvent{Config: w.config})
}
//export onLowMemory
M app/os_js.go => app/os_js.go +4 -2
@@ 258,11 258,13 @@ func (w *window) addEventListeners() {
return nil
})
w.addEventListener(w.tarea, "focus", func(this js.Value, args []js.Value) interface{} {
- w.processEvent(key.FocusEvent{Focus: true})
+ w.config.Focused = true
+ w.processEvent(ConfigEvent{Config: w.config})
return nil
})
w.addEventListener(w.tarea, "blur", func(this js.Value, args []js.Value) interface{} {
- w.processEvent(key.FocusEvent{Focus: false})
+ w.config.Focused = false
+ w.processEvent(ConfigEvent{Config: w.config})
w.blur()
return nil
})
M app/os_macos.go => app/os_macos.go +2 -1
@@ 612,8 612,9 @@ func gio_onDraw(h C.uintptr_t) {
//export gio_onFocus
func gio_onFocus(h C.uintptr_t, focus C.int) {
w := windowFor(h)
- w.ProcessEvent(key.FocusEvent{Focus: focus == 1})
w.SetCursor(w.cursor)
+ w.config.Focused = focus == 1
+ w.ProcessEvent(ConfigEvent{Config: w.config})
}
//export gio_onChangeScreen
M app/os_wayland.go => app/os_wayland.go +4 -2
@@ 1222,7 1222,8 @@ func gio_onKeyboardEnter(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, se
w := callbackLoad(unsafe.Pointer(surf)).(*window)
s.keyboardFocus = w
s.disp.repeat.Stop(0)
- w.ProcessEvent(key.FocusEvent{Focus: true})
+ w.config.Focused = true
+ w.ProcessEvent(ConfigEvent{Config: w.config})
}
//export gio_onKeyboardLeave
@@ 1231,7 1232,8 @@ func gio_onKeyboardLeave(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, se
s.serial = serial
s.disp.repeat.Stop(0)
w := s.keyboardFocus
- w.ProcessEvent(key.FocusEvent{Focus: false})
+ w.config.Focused = false
+ w.ProcessEvent(ConfigEvent{Config: w.config})
}
//export gio_onKeyboardKey
M app/os_windows.go => app/os_windows.go +5 -6
@@ 50,7 50,6 @@ type window struct {
placement *windows.WindowPlacement
animating bool
- focused bool
borderSize image.Point
config Config
@@ 269,11 268,11 @@ func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr
Kind: pointer.Cancel,
})
case windows.WM_SETFOCUS:
- w.focused = true
- w.ProcessEvent(key.FocusEvent{Focus: true})
+ w.config.Focused = true
+ w.ProcessEvent(ConfigEvent{Config: w.config})
case windows.WM_KILLFOCUS:
- w.focused = false
- w.ProcessEvent(key.FocusEvent{Focus: false})
+ w.config.Focused = false
+ w.ProcessEvent(ConfigEvent{Config: w.config})
case windows.WM_NCHITTEST:
if w.config.Decorated {
// Let the system handle it.
@@ 496,7 495,7 @@ func (w *window) hitTest(x, y int) uintptr {
}
func (w *window) pointerButton(btn pointer.Buttons, press bool, lParam uintptr, kmods key.Modifiers) {
- if !w.focused {
+ if !w.config.Focused {
windows.SetFocus(w.hwnd)
}
M app/os_x11.go => app/os_x11.go +4 -2
@@ 657,9 657,11 @@ func (h *x11EventHandler) handleEvents() bool {
// redraw only on the last expose event
redraw = (*C.XExposeEvent)(unsafe.Pointer(xev)).count == 0
case C.FocusIn:
- w.ProcessEvent(key.FocusEvent{Focus: true})
+ w.config.Focused = true
+ w.ProcessEvent(ConfigEvent{Config: w.config})
case C.FocusOut:
- w.ProcessEvent(key.FocusEvent{Focus: false})
+ w.config.Focused = false
+ w.ProcessEvent(ConfigEvent{Config: w.config})
case C.ConfigureNotify: // window configuration change
cevt := (*C.XConfigureEvent)(unsafe.Pointer(xev))
if sz := image.Pt(int(cevt.width), int(cevt.height)); sz != w.config.Size {
M app/window.go => app/window.go +10 -0
@@ 630,9 630,19 @@ func (w *Window) processEvent(e event.Event) bool {
}
w.coalesced.view = &e2
case ConfigEvent:
+ wasFocused := w.decorations.Config.Focused
w.decorations.Config = e2.Config
e2.Config = w.effectiveConfig()
w.coalesced.cfg = &e2
+ if f := w.decorations.Config.Focused; f != wasFocused {
+ w.queue.Queue(key.FocusEvent{Focus: f})
+ }
+ t, handled := w.queue.WakeupTime()
+ if handled {
+ w.setNextFrame(t)
+ w.updateAnimation()
+ }
+ return handled
case event.Event:
focusDir := key.FocusDirection(-1)
if e, ok := e2.(key.Event); ok && e.State == key.Press {