diff options
author | Ilija Boshkov <ilija.boshkov@gmail.com> | 2017-01-25 19:21:41 +0100 |
---|---|---|
committer | RĂ©mi Verschelde <rverschelde@gmail.com> | 2017-01-25 19:21:41 +0100 |
commit | 1005a56e5a27fb7f491d280d5aff6fe88691365c (patch) | |
tree | 3b6ba52457db0287feed818955b3f917c5485b7b /platform/x11 | |
parent | 4c28f35b2c6dacd30a0e10453af1bcd977de9342 (diff) |
Added focus tracking in X11 and Windows classes, added new confined mouse mode (#7162)
Diffstat (limited to 'platform/x11')
-rw-r--r-- | platform/x11/os_x11.cpp | 59 | ||||
-rw-r--r-- | platform/x11/os_x11.h | 2 |
2 files changed, 41 insertions, 20 deletions
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 8baeb8bc90..38f7233c78 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -450,6 +450,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi physics_2d_server->init(); input = memnew( InputDefault ); + + window_has_focus = true; // Set focus to true at init #ifdef JOYDEV_ENABLED joypad = memnew( JoypadLinux(input)); #endif @@ -518,17 +520,21 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) { if (p_mode==mouse_mode) return; - if (mouse_mode==MOUSE_MODE_CAPTURED) + if (mouse_mode==MOUSE_MODE_CAPTURED || mouse_mode==MOUSE_MODE_CONFINED) XUngrabPointer(x11_display, CurrentTime); - if (mouse_mode!=MOUSE_MODE_VISIBLE && p_mode==MOUSE_MODE_VISIBLE) - XUndefineCursor(x11_display,x11_window); - if (p_mode!=MOUSE_MODE_VISIBLE && mouse_mode==MOUSE_MODE_VISIBLE) { - XDefineCursor(x11_display,x11_window,null_cursor); + + // The only modes that show a cursor are VISIBLE and CONFINED + bool showCursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED); + + if (showCursor) { + XUndefineCursor(x11_display,x11_window); // show cursor + } else { + XDefineCursor(x11_display,x11_window,null_cursor); // hide cursor } mouse_mode=p_mode; - if (mouse_mode==MOUSE_MODE_CAPTURED) { + if (mouse_mode==MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { while(true) { //flush pending motion events @@ -1254,6 +1260,10 @@ void OS_X11::process_xevents() { do_mouse_warp=false; + + // Is the current mouse mode one where it needs to be grabbed. + bool mouse_mode_grab = mouse_mode==MOUSE_MODE_CAPTURED || mouse_mode==MOUSE_MODE_CONFINED; + while (XPending(x11_display) > 0) { XEvent event; XNextEvent(x11_display, &event); @@ -1272,35 +1282,45 @@ void OS_X11::process_xevents() { minimized = (visibility->state == VisibilityFullyObscured); } break; case LeaveNotify: { - - if (main_loop && mouse_mode!=MOUSE_MODE_CAPTURED) + if (main_loop && !mouse_mode_grab) main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT); if (input) input->set_mouse_in_window(false); } break; case EnterNotify: { - - if (main_loop && mouse_mode!=MOUSE_MODE_CAPTURED) + if (main_loop && !mouse_mode_grab) main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER); if (input) input->set_mouse_in_window(true); } break; case FocusIn: minimized = false; + window_has_focus = true; main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); - if (mouse_mode==MOUSE_MODE_CAPTURED) { + if (mouse_mode_grab) { + // Show and update the cursor if confined and the window regained focus. + if (mouse_mode==MOUSE_MODE_CONFINED) + XUndefineCursor(x11_display, x11_window); + else if (mouse_mode==MOUSE_MODE_CAPTURED) // or re-hide it in captured mode + XDefineCursor(x11_display, x11_window, null_cursor); + XGrabPointer( - x11_display, x11_window, True, + x11_display, x11_window, True, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime); } break; case FocusOut: + window_has_focus = false; main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); - if (mouse_mode==MOUSE_MODE_CAPTURED) { + if (mouse_mode_grab) { //dear X11, I try, I really try, but you never work, you do whathever you want. + if (mouse_mode==MOUSE_MODE_CAPTURED) { + // Show the cursor if we're in captured mode so it doesn't look weird. + XUndefineCursor(x11_display, x11_window); + } XUngrabPointer(x11_display, CurrentTime); } break; @@ -1320,7 +1340,7 @@ void OS_X11::process_xevents() { /* exit in case of a mouse button press */ last_timestamp=event.xbutton.time; - if (mouse_mode==MOUSE_MODE_CAPTURED) { + if (mouse_mode == MOUSE_MODE_CAPTURED) { event.xbutton.x=last_mouse_pos.x; event.xbutton.y=last_mouse_pos.y; } @@ -1343,7 +1363,6 @@ void OS_X11::process_xevents() { mouse_event.mouse_button.pressed=(event.type==ButtonPress); - if (event.type==ButtonPress && event.xbutton.button==1) { uint64_t diff = get_ticks_usec()/1000 - last_click_ms; @@ -1377,7 +1396,6 @@ void OS_X11::process_xevents() { // PLEASE DO ME A FAVOR AND DIE DROWNED IN A FECAL // MOUNTAIN BECAUSE THAT'S WHERE YOU BELONG. - while(true) { if (mouse_mode==MOUSE_MODE_CAPTURED && event.xmotion.x==current_videomode.width/2 && event.xmotion.y==current_videomode.height/2) { //this is likely the warp event since it was warped here @@ -1419,7 +1437,7 @@ void OS_X11::process_xevents() { Point2i new_center = pos; pos = last_mouse_pos + ( pos - center ); center=new_center; - do_mouse_warp=true; + do_mouse_warp=window_has_focus; // warp the cursor if we're focused in #else //Dear X11, thanks for making my life miserable @@ -1462,8 +1480,11 @@ void OS_X11::process_xevents() { last_mouse_pos=pos; // printf("rel: %d,%d\n", rel.x, rel.y ); - - input->parse_input_event( motion_event); + // Don't propagate the motion event unless we have focus + // this is so that the relative motion doesn't get messed up + // after we regain focus. + if (window_has_focus || !mouse_mode_grab) + input->parse_input_event( motion_event); } break; case KeyPress: diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 3245df32c6..3ec358f103 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -134,7 +134,7 @@ class OS_X11 : public OS_Unix { bool force_quit; bool minimized; - + bool window_has_focus; bool do_mouse_warp; const char *cursor_theme; |