From 9fe8b684e2a5ac4caea811154db1f2bfd74b2b7b Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Tue, 19 Dec 2023 11:22:54 -0600 Subject: [PATCH] app: introduce Config.Focused that tracks the window focus state Signed-off-by: Elias Naur --- app/os.go | 2 ++ app/os_android.go | 3 ++- app/os_ios.go | 3 ++- app/os_js.go | 6 ++++-- app/os_macos.go | 3 ++- app/os_wayland.go | 6 ++++-- app/os_windows.go | 11 +++++------ app/os_x11.go | 6 ++++-- app/window.go | 10 ++++++++++ 9 files changed, 35 insertions(+), 15 deletions(-) diff --git a/app/os.go b/app/os.go index 373210b1..36a01034 100644 --- a/app/os.go +++ b/app/os.go @@ -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 diff --git a/app/os_android.go b/app/os_android.go index f16cf934..a18bd083 100644 --- a/app/os_android.go +++ b/app/os_android.go @@ -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 diff --git a/app/os_ios.go b/app/os_ios.go index 2ce093cb..34163e63 100644 --- a/app/os_ios.go +++ b/app/os_ios.go @@ -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 diff --git a/app/os_js.go b/app/os_js.go index 536a1223..79e02783 100644 --- a/app/os_js.go +++ b/app/os_js.go @@ -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 }) diff --git a/app/os_macos.go b/app/os_macos.go index 6be39508..b0e5526e 100644 --- a/app/os_macos.go +++ b/app/os_macos.go @@ -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 diff --git a/app/os_wayland.go b/app/os_wayland.go index b3436af5..550a4917 100644 --- a/app/os_wayland.go +++ b/app/os_wayland.go @@ -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 diff --git a/app/os_windows.go b/app/os_windows.go index 089a305a..72489270 100644 --- a/app/os_windows.go +++ b/app/os_windows.go @@ -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) } diff --git a/app/os_x11.go b/app/os_x11.go index 32df7407..f5ea42a6 100644 --- a/app/os_x11.go +++ b/app/os_x11.go @@ -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 { diff --git a/app/window.go b/app/window.go index 9b28cbd5..61da5b58 100644 --- a/app/window.go +++ b/app/window.go @@ -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 { -- 2.45.2