diff options
-rw-r--r-- | core/input/input.cpp | 3 | ||||
-rw-r--r-- | core/input/input.h | 3 | ||||
-rw-r--r-- | doc/classes/DisplayServer.xml | 8 | ||||
-rw-r--r-- | doc/classes/Input.xml | 5 | ||||
-rw-r--r-- | platform/javascript/display_server_javascript.cpp | 5 | ||||
-rw-r--r-- | platform/linuxbsd/display_server_x11.cpp | 8 | ||||
-rw-r--r-- | platform/osx/display_server_osx.mm | 11 | ||||
-rw-r--r-- | platform/uwp/app.cpp | 6 | ||||
-rw-r--r-- | platform/uwp/os_uwp.cpp | 4 | ||||
-rw-r--r-- | platform/windows/display_server_windows.cpp | 49 | ||||
-rw-r--r-- | servers/display_server.cpp | 1 | ||||
-rw-r--r-- | servers/display_server.h | 3 |
12 files changed, 69 insertions, 37 deletions
diff --git a/core/input/input.cpp b/core/input/input.cpp index 6eafec087d..6e98b596d7 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -85,7 +85,7 @@ Input *Input::get_singleton() { } void Input::set_mouse_mode(MouseMode p_mode) { - ERR_FAIL_INDEX((int)p_mode, 4); + ERR_FAIL_INDEX((int)p_mode, 5); set_mouse_mode_func(p_mode); } @@ -138,6 +138,7 @@ void Input::_bind_methods() { BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN); BIND_ENUM_CONSTANT(MOUSE_MODE_CAPTURED); BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED); + BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED_HIDDEN); BIND_ENUM_CONSTANT(CURSOR_ARROW); BIND_ENUM_CONSTANT(CURSOR_IBEAM); diff --git a/core/input/input.h b/core/input/input.h index 99b45db325..ecb4981b13 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -46,7 +46,8 @@ public: MOUSE_MODE_VISIBLE, MOUSE_MODE_HIDDEN, MOUSE_MODE_CAPTURED, - MOUSE_MODE_CONFINED + MOUSE_MODE_CONFINED, + MOUSE_MODE_CONFINED_HIDDEN, }; #undef CursorShape diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index 0c9df071a7..6c1cd37beb 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -1044,12 +1044,20 @@ <constant name="FEATURE_SWAP_BUFFERS" value="17" enum="Feature"> </constant> <constant name="MOUSE_MODE_VISIBLE" value="0" enum="MouseMode"> + Makes the mouse cursor visible if it is hidden. </constant> <constant name="MOUSE_MODE_HIDDEN" value="1" enum="MouseMode"> + Makes the mouse cursor hidden if it is visible. </constant> <constant name="MOUSE_MODE_CAPTURED" value="2" enum="MouseMode"> + Captures the mouse. The mouse will be hidden and its position locked at the center of the screen. + [b]Note:[/b] If you want to process the mouse's movement in this mode, you need to use [member InputEventMouseMotion.relative]. </constant> <constant name="MOUSE_MODE_CONFINED" value="3" enum="MouseMode"> + Confines the mouse cursor to the game window, and make it visible. + </constant> + <constant name="MOUSE_MODE_CONFINED_HIDDEN" value="4" enum="MouseMode"> + Confines the mouse cursor to the game window, and make it hidden. </constant> <constant name="SCREEN_OF_MAIN_WINDOW" value="-1"> </constant> diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index d7408cd0ff..ebfd32c5fb 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -449,7 +449,10 @@ [b]Note:[/b] If you want to process the mouse's movement in this mode, you need to use [member InputEventMouseMotion.relative]. </constant> <constant name="MOUSE_MODE_CONFINED" value="3" enum="MouseMode"> - Makes the mouse cursor visible but confines it to the game window. + Confines the mouse cursor to the game window, and make it visible. + </constant> + <constant name="MOUSE_MODE_CONFINED_HIDDEN" value="4" enum="MouseMode"> + Confines the mouse cursor to the game window, and make it hidden. </constant> <constant name="CURSOR_ARROW" value="0" enum="CursorShape"> Arrow cursor. Standard, default pointing cursor. diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp index cce1f8dca7..1cc05a2e19 100644 --- a/platform/javascript/display_server_javascript.cpp +++ b/platform/javascript/display_server_javascript.cpp @@ -407,9 +407,10 @@ void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, Curso // Mouse mode void DisplayServerJavaScript::mouse_set_mode(MouseMode p_mode) { - ERR_FAIL_COND_MSG(p_mode == MOUSE_MODE_CONFINED, "MOUSE_MODE_CONFINED is not supported for the HTML5 platform."); - if (p_mode == mouse_get_mode()) + ERR_FAIL_COND_MSG(p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN, "MOUSE_MODE_CONFINED is not supported for the HTML5 platform."); + if (p_mode == mouse_get_mode()) { return; + } if (p_mode == MOUSE_MODE_VISIBLE) { godot_js_display_cursor_set_visible(1); diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index b50b5f3479..8b6922699c 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -360,7 +360,7 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) { return; } - if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { + if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { XUngrabPointer(x11_display, CurrentTime); } @@ -376,7 +376,7 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) { } mouse_mode = p_mode; - if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { + if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { //flush pending motion events _flush_mouse_motion(); WindowData &main_window = windows[MAIN_WINDOW_ID]; @@ -2766,7 +2766,7 @@ void DisplayServerX11::process_events() { 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; + bool mouse_mode_grab = mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN; xi.pressure = 0; xi.tilt = Vector2(); @@ -3030,7 +3030,7 @@ void DisplayServerX11::process_events() { for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { if (mouse_mode == MOUSE_MODE_CONFINED) { XUndefineCursor(x11_display, E->get().x11_window); - } else if (mouse_mode == MOUSE_MODE_CAPTURED) { // or re-hide it in captured mode + } else if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { // Or re-hide it. XDefineCursor(x11_display, E->get().x11_window, null_cursor); } diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index f53b60891f..408feb4db9 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -884,7 +884,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i return; } - if (DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED) { + if (DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED || DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED_HIDDEN) { // Discard late events if (([event timestamp]) < DS_OSX->last_warp) { return; @@ -2106,7 +2106,12 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) { } else if (p_mode == MOUSE_MODE_CONFINED) { CGDisplayShowCursor(kCGDirectMainDisplay); CGAssociateMouseAndMouseCursorPosition(false); - } else { + } else if (p_mode == MOUSE_MODE_CONFINED_HIDDEN) { + if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { + CGDisplayHideCursor(kCGDirectMainDisplay); + } + CGAssociateMouseAndMouseCursorPosition(false); + } else { // MOUSE_MODE_VISIBLE CGDisplayShowCursor(kCGDirectMainDisplay); CGAssociateMouseAndMouseCursorPosition(true); } @@ -2143,7 +2148,7 @@ void DisplayServerOSX::mouse_warp_to_position(const Point2i &p_to) { CGEventSourceSetLocalEventsSuppressionInterval(lEventRef, 0.0); CGAssociateMouseAndMouseCursorPosition(false); CGWarpMouseCursorPosition(lMouseWarpPos); - if (mouse_mode != MOUSE_MODE_CONFINED) { + if (mouse_mode != MOUSE_MODE_CONFINED && mouse_mode != MOUSE_MODE_CONFINED_HIDDEN) { CGAssociateMouseAndMouseCursorPosition(true); } } diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp index 9d6ff10483..bac8620086 100644 --- a/platform/uwp/app.cpp +++ b/platform/uwp/app.cpp @@ -333,8 +333,9 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co os->input_event(screen_drag); } else { // In case the mouse grabbed, MouseMoved will handle this - if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED) + if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED) { return; + } Ref<InputEventMouseMotion> mouse_motion; mouse_motion.instance(); @@ -351,8 +352,9 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) { // In case the mouse isn't grabbed, PointerMoved will handle this - if (os->get_mouse_mode() != OS::MouseMode::MOUSE_MODE_CAPTURED) + if (os->get_mouse_mode() != OS::MouseMode::MOUSE_MODE_CAPTURED) { return; + } Windows::Foundation::Point pos; pos.X = last_mouse_pos.X + args->MouseDelta.X; diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 435f829c9b..65934b6681 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -400,14 +400,12 @@ void OS_UWP::ManagedType::on_gyroscope_reading_changed(Gyrometer ^ sender, Gyrom void OS_UWP::set_mouse_mode(MouseMode p_mode) { if (p_mode == MouseMode::MOUSE_MODE_CAPTURED) { CoreWindow::GetForCurrentThread()->SetPointerCapture(); - } else { CoreWindow::GetForCurrentThread()->ReleasePointerCapture(); } - if (p_mode == MouseMode::MOUSE_MODE_CAPTURED || p_mode == MouseMode::MOUSE_MODE_HIDDEN) { + if (p_mode == MouseMode::MOUSE_MODE_HIDDEN || p_mode == MouseMode::MOUSE_MODE_CAPTURED || p_mode == MouseMode::MOUSE_MODE_CONFINED_HIDDEN) { CoreWindow::GetForCurrentThread()->PointerCursor = nullptr; - } else { CoreWindow::GetForCurrentThread()->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); } diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 4dd3151eb3..03ccf6c059 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -84,7 +84,8 @@ void DisplayServerWindows::alert(const String &p_alert, const String &p_title) { } void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) { - if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED) { + if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN) { + // Mouse is grabbed (captured or confined). WindowData &wd = windows[MAIN_WINDOW_ID]; RECT clipRect; @@ -100,11 +101,12 @@ void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) { SetCapture(wd.hWnd); } } else { + // Mouse is free to move around (not captured or confined). ReleaseCapture(); ClipCursor(nullptr); } - if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_HIDDEN) { + if (p_mode == MOUSE_MODE_HIDDEN || p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED_HIDDEN) { if (hCursor == nullptr) { hCursor = SetCursor(nullptr); } else { @@ -715,7 +717,7 @@ void DisplayServerWindows::window_set_position(const Point2i &p_position, Window MoveWindow(wd.hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); #endif // Don't let the mouse leave the window when moved - if (mouse_mode == MOUSE_MODE_CONFINED) { + if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { RECT rect; GetClientRect(wd.hWnd, &rect); ClientToScreen(wd.hWnd, (POINT *)&rect.left); @@ -841,7 +843,7 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo MoveWindow(wd.hWnd, rect.left, rect.top, w, h, TRUE); // Don't let the mouse leave the window when resizing to a smaller resolution - if (mouse_mode == MOUSE_MODE_CONFINED) { + if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { RECT crect; GetClientRect(wd.hWnd, &crect); ClientToScreen(wd.hWnd, (POINT *)&crect.left); @@ -2189,8 +2191,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } // Don't calculate relative mouse movement if we don't have focus in CAPTURED mode. - if (!windows[window_id].window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED) + if (!windows[window_id].window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED) { break; + } Ref<InputEventMouseMotion> mm; mm.instance(); @@ -2294,8 +2297,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } // Don't calculate relative mouse movement if we don't have focus in CAPTURED mode. - if (!windows[window_id].window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED) + if (!windows[window_id].window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED) { break; + } Ref<InputEventMouseMotion> mm; mm.instance(); @@ -2427,20 +2431,23 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_MOUSEWHEEL: { mb->set_pressed(true); int motion = (short)HIWORD(wParam); - if (!motion) + if (!motion) { return 0; + } - if (motion > 0) + if (motion > 0) { mb->set_button_index(MOUSE_BUTTON_WHEEL_UP); - else + } else { mb->set_button_index(MOUSE_BUTTON_WHEEL_DOWN); + } } break; case WM_MOUSEHWHEEL: { mb->set_pressed(true); int motion = (short)HIWORD(wParam); - if (!motion) + if (!motion) { return 0; + } if (motion < 0) { mb->set_button_index(MOUSE_BUTTON_WHEEL_LEFT); @@ -2452,24 +2459,27 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } break; case WM_XBUTTONDOWN: { mb->set_pressed(true); - if (HIWORD(wParam) == XBUTTON1) + if (HIWORD(wParam) == XBUTTON1) { mb->set_button_index(MOUSE_BUTTON_XBUTTON1); - else + } else { mb->set_button_index(MOUSE_BUTTON_XBUTTON2); + } } break; case WM_XBUTTONUP: { mb->set_pressed(false); - if (HIWORD(wParam) == XBUTTON1) + if (HIWORD(wParam) == XBUTTON1) { mb->set_button_index(MOUSE_BUTTON_XBUTTON1); - else + } else { mb->set_button_index(MOUSE_BUTTON_XBUTTON2); + } } break; case WM_XBUTTONDBLCLK: { mb->set_pressed(true); - if (HIWORD(wParam) == XBUTTON1) + if (HIWORD(wParam) == XBUTTON1) { mb->set_button_index(MOUSE_BUTTON_XBUTTON1); - else + } else { mb->set_button_index(MOUSE_BUTTON_XBUTTON2); + } mb->set_double_click(true); } break; default: { @@ -2481,10 +2491,11 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mb->set_shift_pressed((wParam & MK_SHIFT) != 0); mb->set_alt_pressed(alt_mem); //mb->is_alt_pressed()=(wParam&MK_MENU)!=0; - if (mb->is_pressed()) + if (mb->is_pressed()) { last_button_state |= (1 << (mb->get_button_index() - 1)); - else + } else { last_button_state &= ~(1 << (mb->get_button_index() - 1)); + } mb->set_button_mask(last_button_state); mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); @@ -2726,7 +2737,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } break; case WM_SETCURSOR: { if (LOWORD(lParam) == HTCLIENT) { - if (windows[window_id].window_has_focus && (mouse_mode == MOUSE_MODE_HIDDEN || mouse_mode == MOUSE_MODE_CAPTURED)) { + if (windows[window_id].window_has_focus && (mouse_mode == MOUSE_MODE_HIDDEN || mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN)) { //Hide the cursor if (hCursor == nullptr) { hCursor = SetCursor(nullptr); diff --git a/servers/display_server.cpp b/servers/display_server.cpp index c7d444c993..ded4b849ef 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -509,6 +509,7 @@ void DisplayServer::_bind_methods() { BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN); BIND_ENUM_CONSTANT(MOUSE_MODE_CAPTURED); BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED); + BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED_HIDDEN); BIND_CONSTANT(SCREEN_OF_MAIN_WINDOW); BIND_CONSTANT(MAIN_WINDOW_ID); diff --git a/servers/display_server.h b/servers/display_server.h index c108281aff..b8201f6fd5 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -142,7 +142,8 @@ public: MOUSE_MODE_VISIBLE, MOUSE_MODE_HIDDEN, MOUSE_MODE_CAPTURED, - MOUSE_MODE_CONFINED + MOUSE_MODE_CONFINED, + MOUSE_MODE_CONFINED_HIDDEN, }; virtual void mouse_set_mode(MouseMode p_mode); |