app: introduce Config.Focused that tracks the window focus state

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2023-12-19 11:22:54 -06:00
parent 35785e9c96
commit 993ec907be
9 changed files with 35 additions and 15 deletions
+2
View File
@@ -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
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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
+4 -2
View File
@@ -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
})
+2 -1
View File
@@ -623,8 +623,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
+4 -2
View File
@@ -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
+5 -6
View File
@@ -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)
}
+4 -2
View File
@@ -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 {
+10
View File
@@ -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 {