From 6d35cfe3a20d0c68c82345cc9a3454a682408850 Mon Sep 17 00:00:00 2001 From: samstalhandske Date: Mon, 26 Jan 2026 20:42:30 +0100 Subject: [PATCH] Focus event --- window.odin | 48 ++++++++++++++++++++++++++++++++++++++++- window_windows.odin | 52 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 2 deletions(-) diff --git a/window.odin b/window.odin index a42fa84..8946245 100644 --- a/window.odin +++ b/window.odin @@ -6,6 +6,7 @@ import "core:fmt" Window :: struct { title: string, width, height: u16, + focused: bool, backend: Backend_Info, @@ -16,12 +17,17 @@ Event_Queue :: queue.Queue(Event) Event :: union { Event_Quit, + Event_Focus, Event_Input, Event_Resize, } Event_Quit :: struct {} +Event_Focus :: struct { + is_focused: bool, +} + Event_Input_State :: enum { Up, Down, @@ -82,6 +88,7 @@ create :: proc(width, height: u16) -> (^Window, bool) { } set_title(w, "Window") + // show_cursor(w, true) return w, true } @@ -99,6 +106,33 @@ set_title :: proc(window: ^Window, title: string) { } } +show_cursor :: proc(window: ^Window, show: bool) { + when ODIN_OS == .Windows { + show_cursor_window(window, show) + } + else { + #assert(false, "Missing implementation for 'show_cursor'.") + } +} + +cursor_visible :: proc(window: ^Window) -> bool { + when ODIN_OS == .Windows { + return cursor_visible_windows(window) + } + else { + #assert(false, "Missing implementation for 'cursor_visible'.") + } + + return false +} + +set_cursor_position :: proc(window: ^Window, pos: [2]u32) { + // fmt.printfln("Set cursor pos: %v:%v", pos.x, pos.y) + when ODIN_OS == .Windows { + set_cursor_position_windows(window, pos) + } +} + get_pointer_to_surface :: proc(window: ^Window) -> rawptr { when ODIN_OS == .Windows { return window.backend.hwnd @@ -116,7 +150,7 @@ update :: proc(window: ^Window, out_event: ^Event) -> bool { update_windows(window) } else { - #assert(false, "Missing implementation for 'set_title'.") + #assert(false, "Missing implementation for 'update'.") } out_event^ = nil @@ -126,6 +160,18 @@ update :: proc(window: ^Window, out_event: ^Event) -> bool { return false } + switch e in event { + case Event_Quit: {} + case Event_Focus: { + window.focused = e.is_focused + } + case Event_Resize: { + window.width = e.new_width + window.height = e.new_height + } + case Event_Input: {} + } + assert(event != nil) out_event^ = event diff --git a/window_windows.odin b/window_windows.odin index 79b24c5..3ea0bff 100644 --- a/window_windows.odin +++ b/window_windows.odin @@ -1,3 +1,4 @@ +#+private package window import "core:container/queue" @@ -36,6 +37,13 @@ Backend_Info :: struct { event_queue := get_event_queue(hwnd) switch(msg) { case win.WM_CREATE: return wm_create(hwnd, lparam) + case win.WM_SETFOCUS, win.WM_KILLFOCUS: { + if event_queue != nil { + queue.push_back(event_queue, Event_Focus { + is_focused = msg == win.WM_SETFOCUS + }) + } + } case win.WM_KEYDOWN, win.WM_SYSKEYDOWN: { input_event: Event_Input = Event_Keyboard { virtual_key = get_virtual_key_windows(i32(wparam)), @@ -129,7 +137,7 @@ Backend_Info :: struct { } return 0 - } +} WINDOW_CLASS_NAME :: "ENSENN_WINDOW" @@ -192,6 +200,48 @@ set_title_windows :: proc(window: ^Window) { win.SetWindowTextW(window.backend.hwnd, win.utf8_to_wstring(window.title)) } +show_cursor_window :: proc(window: ^Window, show: bool) { + assert(window != nil) + + if show == cursor_visible_windows(window) { + if show { + fmt.printfln("Tried to show cursor but it's already visible.") + } + else { + fmt.printfln("Tried to hide cursor but it's already not visible.") + } + return + } + + for { // Win32 :))) + counter := win.ShowCursor(show ? win.TRUE : win.FALSE) + if (show && counter >= 0) || (!show && counter < 0) { + break + } + } + + win.ShowCursor(show ? win.TRUE : win.FALSE) +} + +cursor_visible_windows :: proc(window: ^Window) -> bool { + old_count := win.ShowCursor(win.TRUE) + win.ShowCursor(win.FALSE) + return old_count >= 0 +} + +set_cursor_position_windows :: proc(window: ^Window, pos: [2]u32) { + pt := win.POINT { x = i32(pos.x), y = i32(pos.y) } + rect: win.RECT + win.GetClientRect(window.backend.hwnd, &rect) + + ok := win.ClientToScreen(window.backend.hwnd, &pt) + if !ok { + return + } + + win.SetCursorPos(pt.x, pt.y) +} + update_windows :: proc(window: ^Window) { assert(window != nil)