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>
This commit is contained in:
		
							parent
							
								
									74d9dc69ab
								
							
						
					
					
						commit
						35b0f23720
					
				
							
								
								
									
										43
									
								
								ui/sdl.c
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								ui/sdl.c
									
									
									
									
									
								
							@ -490,15 +490,12 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    if (kbd_mouse_is_absolute()) {
 | 
					    if (kbd_mouse_is_absolute()) {
 | 
				
			||||||
        if (!absolute_enabled) {
 | 
					        if (!absolute_enabled) {
 | 
				
			||||||
            sdl_hide_cursor();
 | 
					            sdl_grab_start();
 | 
				
			||||||
            if (gui_grab) {
 | 
					 | 
				
			||||||
                sdl_grab_end();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            absolute_enabled = 1;
 | 
					            absolute_enabled = 1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else if (absolute_enabled) {
 | 
					    } else if (absolute_enabled) {
 | 
				
			||||||
	sdl_show_cursor();
 | 
					        sdl_grab_end();
 | 
				
			||||||
	absolute_enabled = 0;
 | 
					        absolute_enabled = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -572,6 +569,19 @@ static void toggle_full_screen(DisplayState *ds)
 | 
				
			|||||||
    vga_hw_update();
 | 
					    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)
 | 
					static void sdl_refresh(DisplayState *ds)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SDL_Event ev1, *ev = &ev1;
 | 
					    SDL_Event ev1, *ev = &ev1;
 | 
				
			||||||
@ -638,6 +648,7 @@ static void sdl_refresh(DisplayState *ds)
 | 
				
			|||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        } else if (absolute_enabled) {
 | 
					                        } else if (absolute_enabled) {
 | 
				
			||||||
                            sdl_hide_cursor();
 | 
					                            sdl_hide_cursor();
 | 
				
			||||||
 | 
					                            absolute_mouse_grab();
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    default:
 | 
					                    default:
 | 
				
			||||||
@ -724,6 +735,22 @@ static void sdl_refresh(DisplayState *ds)
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case SDL_MOUSEMOTION:
 | 
					        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() ||
 | 
					            if (gui_grab || kbd_mouse_is_absolute() ||
 | 
				
			||||||
                absolute_enabled) {
 | 
					                absolute_enabled) {
 | 
				
			||||||
                sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0,
 | 
					                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) {
 | 
					                !ev->active.gain && !gui_fullscreen) {
 | 
				
			||||||
                sdl_grab_end();
 | 
					                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.state & SDL_APPACTIVE) {
 | 
				
			||||||
                if (ev->active.gain) {
 | 
					                if (ev->active.gain) {
 | 
				
			||||||
                    /* Back to default interval */
 | 
					                    /* Back to default interval */
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user