mirror of
https://github.com/dingusdev/dingusppc.git
synced 2026-04-20 02:17:23 +00:00
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.
This commit is contained in:
@@ -29,7 +29,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
EventManager* EventManager::event_manager;
|
||||
|
||||
static int get_sdl_event_key_code(const SDL_KeyboardEvent& event, uint32_t kbd_locale);
|
||||
static void toggle_mouse_grab(const SDL_KeyboardEvent &event);
|
||||
|
||||
constexpr int KMOD_ALL = KMOD_LSHIFT | KMOD_RSHIFT | KMOD_LCTRL | KMOD_RCTRL | KMOD_LALT | KMOD_RALT | KMOD_LGUI | KMOD_RGUI;
|
||||
|
||||
@@ -59,7 +58,6 @@ void EventManager::poll_events(uint32_t kbd_locale) {
|
||||
// Control-G: mouse grab
|
||||
if (event.key.keysym.sym == SDLK_g && (SDL_GetModState() & KMOD_ALL) == KMOD_LCTRL) {
|
||||
if (event.type == SDL_KEYUP) {
|
||||
toggle_mouse_grab(event.key);
|
||||
WindowEvent we;
|
||||
we.sub_type = DPPC_WINDOWEVENT_MOUSE_GRAB_CHANGED;
|
||||
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
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void toggle_mouse_grab(const SDL_KeyboardEvent &event) {
|
||||
SDL_Window *window = SDL_GetWindowFromID(event.windowID);
|
||||
if (SDL_GetRelativeMouseMode()) {
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
} else {
|
||||
// If the mouse is initially outside the window, move it to the middle,
|
||||
// so that clicks are handled by the window (instead making it lose
|
||||
// focus, at least with macOS hosts).
|
||||
int mouse_x, mouse_y, window_x, window_y, window_width, window_height;
|
||||
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
||||
SDL_GetWindowPosition(window, &window_x, &window_y);
|
||||
SDL_GetWindowSize(window, &window_width, &window_height);
|
||||
if (mouse_x < window_x || mouse_x >= window_x + window_width ||
|
||||
mouse_y < window_y || mouse_y >= window_y + window_height) {
|
||||
SDL_WarpMouseInWindow(window, window_width / 2, window_height / 2);
|
||||
}
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,8 @@ public:
|
||||
void setup_hw_cursor(std::function<void(uint8_t *dst_buf, int dst_pitch)> draw_hw_cursor,
|
||||
int cursor_width, int cursor_height);
|
||||
void update_window_title();
|
||||
void toggle_mouse_grab();
|
||||
void update_mouse_grab();
|
||||
private:
|
||||
class Impl; // Holds private fields
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
@@ -117,6 +117,7 @@ void Display::update_window_size() {
|
||||
SDL_SetWindowSize(impl->display_wnd,
|
||||
impl->drawable_w / impl->default_scale_x,
|
||||
impl->drawable_h / impl->default_scale_y);
|
||||
this->update_mouse_grab(); // make sure the mouse is still inside the window
|
||||
}
|
||||
|
||||
void Display::configure_dest() {
|
||||
@@ -289,12 +290,40 @@ void Display::handle_events(const WindowEvent& wnd_event) {
|
||||
break;
|
||||
|
||||
case DPPC_WINDOWEVENT_MOUSE_GRAB_CHANGED:
|
||||
this->toggle_mouse_grab();
|
||||
this->update_window_title();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Display::toggle_mouse_grab()
|
||||
{
|
||||
if (SDL_GetRelativeMouseMode()) {
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
} else {
|
||||
this->update_mouse_grab();
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void Display::update_mouse_grab()
|
||||
{
|
||||
if (SDL_GetRelativeMouseMode()) {
|
||||
// If the mouse is initially outside the window, move it to the middle,
|
||||
// so that clicks are handled by the window (instead making it lose
|
||||
// focus, at least with macOS hosts).
|
||||
int mouse_x, mouse_y, window_x, window_y, window_width, window_height;
|
||||
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
||||
SDL_GetWindowPosition(impl->display_wnd, &window_x, &window_y);
|
||||
SDL_GetWindowSize(impl->display_wnd, &window_width, &window_height);
|
||||
if (mouse_x < window_x || mouse_x >= window_x + window_width ||
|
||||
mouse_y < window_y || mouse_y >= window_y + window_height) {
|
||||
SDL_WarpMouseInWindow(impl->display_wnd, window_width / 2, window_height / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Display::update_window_title()
|
||||
{
|
||||
std::string old_window_title = SDL_GetWindowTitle(impl->display_wnd);
|
||||
|
||||
Reference in New Issue
Block a user