Skip to content

Commit 72ef266

Browse files
joevtdingusdev
authored andcommitted
display: Update grabbed mouse when resizing.
If the window's size is reduced such that the grabbed mouse is no longer inside the window, then a mouse click will go to another app. Therefore, check the mouse position and update if necessary every time the window changes size.
1 parent c781ba8 commit 72ef266

3 files changed

Lines changed: 31 additions & 22 deletions

File tree

core/hostevents_sdl.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
2929
EventManager* EventManager::event_manager;
3030

3131
static int get_sdl_event_key_code(const SDL_KeyboardEvent& event, uint32_t kbd_locale);
32-
static void toggle_mouse_grab(const SDL_KeyboardEvent &event);
3332

3433
constexpr int KMOD_ALL = KMOD_LSHIFT | KMOD_RSHIFT | KMOD_LCTRL | KMOD_RCTRL | KMOD_LALT | KMOD_RALT | KMOD_LGUI | KMOD_RGUI;
3534

@@ -59,7 +58,6 @@ void EventManager::poll_events(uint32_t kbd_locale) {
5958
// Control-G: mouse grab
6059
if (event.key.keysym.sym == SDLK_g && (SDL_GetModState() & KMOD_ALL) == KMOD_LCTRL) {
6160
if (event.type == SDL_KEYUP) {
62-
toggle_mouse_grab(event.key);
6361
WindowEvent we;
6462
we.sub_type = DPPC_WINDOWEVENT_MOUSE_GRAB_CHANGED;
6563
we.window_id = event.window.windowID;
@@ -427,23 +425,3 @@ static int get_sdl_event_key_code(const SDL_KeyboardEvent &event, uint32_t kbd_l
427425
}
428426
return -1;
429427
}
430-
431-
static void toggle_mouse_grab(const SDL_KeyboardEvent &event) {
432-
SDL_Window *window = SDL_GetWindowFromID(event.windowID);
433-
if (SDL_GetRelativeMouseMode()) {
434-
SDL_SetRelativeMouseMode(SDL_FALSE);
435-
} else {
436-
// If the mouse is initially outside the window, move it to the middle,
437-
// so that clicks are handled by the window (instead making it lose
438-
// focus, at least with macOS hosts).
439-
int mouse_x, mouse_y, window_x, window_y, window_width, window_height;
440-
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
441-
SDL_GetWindowPosition(window, &window_x, &window_y);
442-
SDL_GetWindowSize(window, &window_width, &window_height);
443-
if (mouse_x < window_x || mouse_x >= window_x + window_width ||
444-
mouse_y < window_y || mouse_y >= window_y + window_height) {
445-
SDL_WarpMouseInWindow(window, window_width / 2, window_height / 2);
446-
}
447-
SDL_SetRelativeMouseMode(SDL_TRUE);
448-
}
449-
}

devices/video/display.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ class Display {
7777
void setup_hw_cursor(std::function<void(uint8_t *dst_buf, int dst_pitch)> draw_hw_cursor,
7878
int cursor_width, int cursor_height);
7979
void update_window_title();
80+
void toggle_mouse_grab();
81+
void update_mouse_grab();
8082
private:
8183
class Impl; // Holds private fields
8284
std::unique_ptr<Impl> impl;

devices/video/display_sdl.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ void Display::update_window_size() {
117117
SDL_SetWindowSize(impl->display_wnd,
118118
impl->drawable_w / impl->default_scale_x,
119119
impl->drawable_h / impl->default_scale_y);
120+
this->update_mouse_grab(); // make sure the mouse is still inside the window
120121
}
121122

122123
void Display::configure_dest() {
@@ -289,12 +290,40 @@ void Display::handle_events(const WindowEvent& wnd_event) {
289290
break;
290291

291292
case DPPC_WINDOWEVENT_MOUSE_GRAB_CHANGED:
293+
this->toggle_mouse_grab();
292294
this->update_window_title();
293295
break;
294296

295297
}
296298
}
297299

300+
void Display::toggle_mouse_grab()
301+
{
302+
if (SDL_GetRelativeMouseMode()) {
303+
SDL_SetRelativeMouseMode(SDL_FALSE);
304+
} else {
305+
this->update_mouse_grab();
306+
SDL_SetRelativeMouseMode(SDL_TRUE);
307+
}
308+
}
309+
310+
void Display::update_mouse_grab()
311+
{
312+
if (SDL_GetRelativeMouseMode()) {
313+
// If the mouse is initially outside the window, move it to the middle,
314+
// so that clicks are handled by the window (instead making it lose
315+
// focus, at least with macOS hosts).
316+
int mouse_x, mouse_y, window_x, window_y, window_width, window_height;
317+
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
318+
SDL_GetWindowPosition(impl->display_wnd, &window_x, &window_y);
319+
SDL_GetWindowSize(impl->display_wnd, &window_width, &window_height);
320+
if (mouse_x < window_x || mouse_x >= window_x + window_width ||
321+
mouse_y < window_y || mouse_y >= window_y + window_height) {
322+
SDL_WarpMouseInWindow(impl->display_wnd, window_width / 2, window_height / 2);
323+
}
324+
}
325+
}
326+
298327
void Display::update_window_title()
299328
{
300329
std::string old_window_title = SDL_GetWindowTitle(impl->display_wnd);

0 commit comments

Comments
 (0)