From db5ab5f63c5a255c130d0bd773ce0fc72becaffa Mon Sep 17 00:00:00 2001 From: joevt Date: Sun, 9 Aug 2026 04:35:46 -0700 Subject: [PATCH] display_sdl: Make auto grab mouse optional. Add a command line option to enable auto grab. Default to the previous behavior before the auto grab feature was added. Add a debugger command to enable or disable auto grab. Notes: Auto grab mouse currently only works for graphics controllers and guest OSs that use a hardware cursor and only if the emulation sets cursor_dirty to true (i.e. not emulation that uses cursor_ovl_cb). --- debugger/debugger.cpp | 16 ++++++++++++++++ devices/video/display_sdl.cpp | 8 +++++++- main.cpp | 5 +++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp index d2ccba19..39e0417b 100644 --- a/debugger/debugger.cpp +++ b/debugger/debugger.cpp @@ -58,6 +58,8 @@ using namespace std; #define COUT08X COUT0_X(8) #define COUT04X COUT0_X(4) +extern bool g_auto_grab_mouse; + static uint32_t str2addr(string& addr_str) { try { return static_cast(stoul(addr_str, NULL, 0)); @@ -116,6 +118,8 @@ static void show_help() { cout << " printenv -- print current NVRAM settings." << endl; cout << " setenv V N -- set NVRAM variable V to value N." << endl; cout << endl; + cout << " autograbmouse H -- auto grab the mouse if H is not zero." << endl; + cout << endl; cout << " restart -- restart the machine" << endl; cout << " quit -- quit the debugger" << endl; cout << endl; @@ -1169,6 +1173,18 @@ void DppcDebugger::enter_debugger() { via_obj->assert_int(irq_bit); }); #endif + } else if (cmd == "autograbmouse") { + cmd = ""; + string value; + int num; + ss >> value; + try { + num = str2num(value); + } catch (invalid_argument& exc) { + cout << exc.what() << endl; + continue; + } + g_auto_grab_mouse = num; } else { if (!cmd.empty()) { cout << "Unknown command: " << cmd << endl; diff --git a/devices/video/display_sdl.cpp b/devices/video/display_sdl.cpp index 486ca4ef..e983a864 100644 --- a/devices/video/display_sdl.cpp +++ b/devices/video/display_sdl.cpp @@ -26,6 +26,8 @@ along with this program. If not, see . #include #include +bool g_auto_grab_mouse = false; + static const char * get_full_screen_mode_string(int scale_mode) { #define onemode(x) case Display::x: return #x ; switch(scale_mode) { @@ -316,6 +318,7 @@ void Display::handle_events(const WindowEvent& wnd_event) { if (wnd_event.window_id == impl->disp_wnd_id) { SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0"); SDL_SetWindowKeyboardGrab(impl->display_wnd, SDL_TRUE); +if (g_auto_grab_mouse) { // When the window (re)gains focus (e.g. the user clicks it), SDL // may have dropped the relative mouse grab on focus loss. Re-grab // it so the guest cursor keeps working; this is the reliable @@ -324,6 +327,7 @@ void Display::handle_events(const WindowEvent& wnd_event) { SDL_SetRelativeMouseMode(SDL_TRUE); this->update_window_title(); } +} } break; @@ -449,7 +453,7 @@ void Display::update_window_title() + " " + std::to_string(int(std::round(impl->renderer_scale_x * 100))) + "%"; if (is_grabbed) new_window_title += " (Grabbed, Ctrl+G to release)"; - else if (impl->guest_cursor_drawn) + else if (!g_auto_grab_mouse || impl->guest_cursor_drawn) new_window_title += " (Press Ctrl+G to grab)"; if (new_window_title != old_window_title) @@ -482,6 +486,7 @@ void Display::update(std::function conver SDL_RenderClear(impl->renderer); SDL_RenderCopy(impl->renderer, impl->disp_texture, NULL, &impl->dest_rect); +if (g_auto_grab_mouse) { bool is_grabbed = SDL_GetRelativeMouseMode(); // The guest draws its own cursor into the framebuffer (hardware cursor). @@ -520,6 +525,7 @@ void Display::update(std::function conver impl->guest_cursor_drawn = draw_hw_cursor; this->update_window_title(); } +} // draw HW cursor if enabled if (draw_hw_cursor) { diff --git a/main.cpp b/main.cpp index 988ff301..ea862580 100644 --- a/main.cpp +++ b/main.cpp @@ -49,6 +49,8 @@ along with this program. If not, see . #endif using namespace std; +extern bool g_auto_grab_mouse; + static void sigint_handler(int signum) { power_on = false; power_off_reason = po_signal_interrupt; @@ -168,6 +170,9 @@ int main(int argc, char** argv) { CLI::Option* machine_opt = emu->add_option("-m,--machine", machine_str, "Specify machine ID"); + emu->add_flag("--auto-grab-mouse", g_auto_grab_mouse, + "The guest cursor causes mouse to be grabbed"); + auto list_cmd = app.add_subcommand("list", "Display available machine configurations and exit");