aboutsummaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2011-07-30 11:39:15 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2011-08-05 10:57:35 -0500
commit35b0f237205dc6a5c9aa3eae14f19ef4d37dafcd (patch)
tree630ae2891b242ea478567466c6d86b9f5e733693 /ui
parent74d9dc69abebdbf22b9473708aefd47ab53475dd (diff)
sdl: Dynamically grab input in absolute mouse mode
Not grabbing the input means that special keys like ALT+TAB are still handled by the host. Improve the usability by grabbing input once the mouse is inside the guest screen, provided the SDL window has the input focus. Release it again when the mouse is moved to any border. Also grab the input when we gain the input focus and the mouse is within the screen limits. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'ui')
-rw-r--r--ui/sdl.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/ui/sdl.c b/ui/sdl.c
index 5ad38d5460..e8ac3bb65b 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -490,15 +490,12 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data)
{
if (kbd_mouse_is_absolute()) {
if (!absolute_enabled) {
- sdl_hide_cursor();
- if (gui_grab) {
- sdl_grab_end();
- }
+ sdl_grab_start();
absolute_enabled = 1;
}
} else if (absolute_enabled) {
- sdl_show_cursor();
- absolute_enabled = 0;
+ sdl_grab_end();
+ absolute_enabled = 0;
}
}
@@ -572,6 +569,19 @@ static void toggle_full_screen(DisplayState *ds)
vga_hw_update();
}
+static void absolute_mouse_grab(void)
+{
+ int mouse_x, mouse_y;
+
+ if (SDL_GetAppState() & SDL_APPINPUTFOCUS) {
+ SDL_GetMouseState(&mouse_x, &mouse_y);
+ if (mouse_x > 0 && mouse_x < real_screen->w - 1 &&
+ mouse_y > 0 && mouse_y < real_screen->h - 1) {
+ sdl_grab_start();
+ }
+ }
+}
+
static void sdl_refresh(DisplayState *ds)
{
SDL_Event ev1, *ev = &ev1;
@@ -638,6 +648,7 @@ static void sdl_refresh(DisplayState *ds)
}
} else if (absolute_enabled) {
sdl_hide_cursor();
+ absolute_mouse_grab();
}
break;
default:
@@ -724,6 +735,22 @@ static void sdl_refresh(DisplayState *ds)
}
break;
case SDL_MOUSEMOTION:
+ if (is_graphic_console() &&
+ (kbd_mouse_is_absolute() || absolute_enabled)) {
+ int max_x = real_screen->w - 1;
+ int max_y = real_screen->h - 1;
+
+ if (gui_grab &&
+ (ev->motion.x == 0 || ev->motion.y == 0 ||
+ ev->motion.x == max_x || ev->motion.y == max_y)) {
+ sdl_grab_end();
+ }
+ if (!gui_grab && SDL_GetAppState() & SDL_APPINPUTFOCUS &&
+ (ev->motion.x > 0 && ev->motion.x < max_x &&
+ ev->motion.y > 0 && ev->motion.y < max_y)) {
+ sdl_grab_start();
+ }
+ }
if (gui_grab || kbd_mouse_is_absolute() ||
absolute_enabled) {
sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0,
@@ -764,6 +791,10 @@ static void sdl_refresh(DisplayState *ds)
!ev->active.gain && !gui_fullscreen) {
sdl_grab_end();
}
+ if (!gui_grab && ev->active.gain && is_graphic_console() &&
+ (kbd_mouse_is_absolute() || absolute_enabled)) {
+ absolute_mouse_grab();
+ }
if (ev->active.state & SDL_APPACTIVE) {
if (ev->active.gain) {
/* Back to default interval */