diff --git a/xbanan/Events.cpp b/xbanan/Events.cpp index 62686dc..74595c0 100644 --- a/xbanan/Events.cpp +++ b/xbanan/Events.cpp @@ -453,7 +453,22 @@ static void send_enter_and_leave_events(WINDOW old_wid, int32_t old_x, int32_t o g_objects[wid]->object.get().hovered = false; for (const auto wid : new_child_path) g_objects[wid]->object.get().hovered = true; +} +static WINDOW s_current_top_level_window = None; + +void on_window_leave_event(WINDOW wid) +{ + if (s_current_top_level_window != wid) + return; + + auto& object = *g_objects[wid]; + ASSERT(object.type == Object::Type::Window); + auto& window = object.object.get(); + + send_enter_and_leave_events(wid, window.cursor_x, window.cursor_y, wid, -1, -1); + + s_current_top_level_window = None; } void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y) @@ -464,24 +479,17 @@ void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y) update_cursor(wid, x, y); + if (auto it = g_objects.find(s_current_top_level_window); it == g_objects.end()) + send_enter_and_leave_events(wid, -1, -1, wid, x, y); + else { - static WINDOW old_wid = g_root.windowId; - - auto it = g_objects.find(old_wid); - if (it == g_objects.end()) - { - old_wid = g_root.windowId; - it = g_objects.find(g_root.windowId); - } - ASSERT(it->value->type == Object::Type::Window); auto& old_window = it->value->object.get(); - - send_enter_and_leave_events(old_wid, old_window.cursor_x, old_window.cursor_y, wid, x, y); - - old_wid = wid; + send_enter_and_leave_events(s_current_top_level_window, old_window.cursor_x, old_window.cursor_y, wid, x, y); } + s_current_top_level_window = wid; + update_cursor_position_recursive(wid, x, y); // TODO: optimize with PointerMotionHint diff --git a/xbanan/Events.h b/xbanan/Events.h index 4926d5f..1ae0a77 100644 --- a/xbanan/Events.h +++ b/xbanan/Events.h @@ -9,6 +9,7 @@ void on_window_close_event(WINDOW wid); void on_window_resize_event(WINDOW wid, uint32_t width, uint32_t height); void on_window_focus_event(WINDOW wid, bool focused); void on_window_fullscreen_event(WINDOW wid, bool is_fullscreen); +void on_window_leave_event(WINDOW wid); void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y); void on_mouse_button_event(WINDOW wid, uint8_t xbutton, bool pressed); diff --git a/xbanan/SDL2/sdl2.cpp b/xbanan/SDL2/sdl2.cpp index c756ede..28f5fbe 100644 --- a/xbanan/SDL2/sdl2.cpp +++ b/xbanan/SDL2/sdl2.cpp @@ -215,6 +215,9 @@ static void sdl2_poll_events(void*) case SDL_WINDOWEVENT_RESTORED: on_window_fullscreen_event(window.wid, false); break; + case SDL_WINDOWEVENT_LEAVE: + on_window_leave_event(window.wid); + break; } break; }