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 2a18a0c135
commit 9fe8b684e2
9 changed files with 35 additions and 15 deletions
+2
View File
@@ -45,6 +45,8 @@ type Config struct {
CustomRenderer bool CustomRenderer bool
// Decorated reports whether window decorations are provided automatically. // Decorated reports whether window decorations are provided automatically.
Decorated bool Decorated bool
// Focused reports whether has the keyboard focus.
Focused bool
// decoHeight is the height of the fallback decoration for platforms such // decoHeight is the height of the fallback decoration for platforms such
// as Wayland that may need fallback client-side decorations. // as Wayland that may need fallback client-side decorations.
decoHeight unit.Dp 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 //export Java_org_gioui_GioView_onFocusChange
func Java_org_gioui_GioView_onFocusChange(env *C.JNIEnv, class C.jclass, view C.jlong, focus C.jboolean) { 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 := 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 //export Java_org_gioui_GioView_onWindowInsets
+2 -1
View File
@@ -211,7 +211,8 @@ func onDestroy(h C.uintptr_t) {
//export onFocus //export onFocus
func onFocus(h C.uintptr_t, focus int) { func onFocus(h C.uintptr_t, focus int) {
w := viewFor(h) w := viewFor(h)
w.ProcessEvent(key.FocusEvent{Focus: focus != 0}) w.config.Focused = focus != 0
w.ProcessEvent(ConfigEvent{Config: w.config})
} }
//export onLowMemory //export onLowMemory
+4 -2
View File
@@ -258,11 +258,13 @@ func (w *window) addEventListeners() {
return nil return nil
}) })
w.addEventListener(w.tarea, "focus", func(this js.Value, args []js.Value) interface{} { 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 return nil
}) })
w.addEventListener(w.tarea, "blur", func(this js.Value, args []js.Value) interface{} { 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() w.blur()
return nil return nil
}) })
+2 -1
View File
@@ -612,8 +612,9 @@ func gio_onDraw(h C.uintptr_t) {
//export gio_onFocus //export gio_onFocus
func gio_onFocus(h C.uintptr_t, focus C.int) { func gio_onFocus(h C.uintptr_t, focus C.int) {
w := windowFor(h) w := windowFor(h)
w.ProcessEvent(key.FocusEvent{Focus: focus == 1})
w.SetCursor(w.cursor) w.SetCursor(w.cursor)
w.config.Focused = focus == 1
w.ProcessEvent(ConfigEvent{Config: w.config})
} }
//export gio_onChangeScreen //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) w := callbackLoad(unsafe.Pointer(surf)).(*window)
s.keyboardFocus = w s.keyboardFocus = w
s.disp.repeat.Stop(0) s.disp.repeat.Stop(0)
w.ProcessEvent(key.FocusEvent{Focus: true}) w.config.Focused = true
w.ProcessEvent(ConfigEvent{Config: w.config})
} }
//export gio_onKeyboardLeave //export gio_onKeyboardLeave
@@ -1231,7 +1232,8 @@ func gio_onKeyboardLeave(data unsafe.Pointer, keyboard *C.struct_wl_keyboard, se
s.serial = serial s.serial = serial
s.disp.repeat.Stop(0) s.disp.repeat.Stop(0)
w := s.keyboardFocus w := s.keyboardFocus
w.ProcessEvent(key.FocusEvent{Focus: false}) w.config.Focused = false
w.ProcessEvent(ConfigEvent{Config: w.config})
} }
//export gio_onKeyboardKey //export gio_onKeyboardKey
+5 -6
View File
@@ -50,7 +50,6 @@ type window struct {
placement *windows.WindowPlacement placement *windows.WindowPlacement
animating bool animating bool
focused bool
borderSize image.Point borderSize image.Point
config Config config Config
@@ -269,11 +268,11 @@ func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr
Kind: pointer.Cancel, Kind: pointer.Cancel,
}) })
case windows.WM_SETFOCUS: case windows.WM_SETFOCUS:
w.focused = true w.config.Focused = true
w.ProcessEvent(key.FocusEvent{Focus: true}) w.ProcessEvent(ConfigEvent{Config: w.config})
case windows.WM_KILLFOCUS: case windows.WM_KILLFOCUS:
w.focused = false w.config.Focused = false
w.ProcessEvent(key.FocusEvent{Focus: false}) w.ProcessEvent(ConfigEvent{Config: w.config})
case windows.WM_NCHITTEST: case windows.WM_NCHITTEST:
if w.config.Decorated { if w.config.Decorated {
// Let the system handle it. // 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) { 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) 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 only on the last expose event
redraw = (*C.XExposeEvent)(unsafe.Pointer(xev)).count == 0 redraw = (*C.XExposeEvent)(unsafe.Pointer(xev)).count == 0
case C.FocusIn: case C.FocusIn:
w.ProcessEvent(key.FocusEvent{Focus: true}) w.config.Focused = true
w.ProcessEvent(ConfigEvent{Config: w.config})
case C.FocusOut: 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 case C.ConfigureNotify: // window configuration change
cevt := (*C.XConfigureEvent)(unsafe.Pointer(xev)) cevt := (*C.XConfigureEvent)(unsafe.Pointer(xev))
if sz := image.Pt(int(cevt.width), int(cevt.height)); sz != w.config.Size { 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 w.coalesced.view = &e2
case ConfigEvent: case ConfigEvent:
wasFocused := w.decorations.Config.Focused
w.decorations.Config = e2.Config w.decorations.Config = e2.Config
e2.Config = w.effectiveConfig() e2.Config = w.effectiveConfig()
w.coalesced.cfg = &e2 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: case event.Event:
focusDir := key.FocusDirection(-1) focusDir := key.FocusDirection(-1)
if e, ok := e2.(key.Event); ok && e.State == key.Press { if e, ok := e2.(key.Event); ok && e.State == key.Press {