Delegate to the DisplayServer the task of handling mouse_mode

- Add `MOUSE_MODE_MAX` and various index checks
This commit is contained in:
Adam Scott 2025-01-22 10:44:50 -05:00
parent b15b24b087
commit 47f553ae0b
No known key found for this signature in database
GPG Key ID: F6BA2A0302E21A77
19 changed files with 395 additions and 78 deletions

View File

@ -77,6 +77,10 @@ Input *Input::singleton = nullptr;
void (*Input::set_mouse_mode_func)(Input::MouseMode) = nullptr;
Input::MouseMode (*Input::get_mouse_mode_func)() = nullptr;
void (*Input::set_mouse_mode_override_func)(Input::MouseMode) = nullptr;
Input::MouseMode (*Input::get_mouse_mode_override_func)() = nullptr;
void (*Input::set_mouse_mode_override_enabled_func)(bool) = nullptr;
bool (*Input::is_mouse_mode_override_enabled_func)() = nullptr;
void (*Input::warp_mouse_func)(const Vector2 &p_position) = nullptr;
Input::CursorShape (*Input::get_current_cursor_shape_func)() = nullptr;
void (*Input::set_custom_mouse_cursor_func)(const Ref<Resource> &, Input::CursorShape, const Vector2 &) = nullptr;
@ -86,51 +90,29 @@ Input *Input::get_singleton() {
}
void Input::set_mouse_mode(MouseMode p_mode) {
ERR_FAIL_INDEX((int)p_mode, 5);
if (p_mode == mouse_mode) {
return;
}
// Allow to be set even if overridden, to see if the platform allows the mode.
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
set_mouse_mode_func(p_mode);
mouse_mode = get_mouse_mode_func();
if (mouse_mode_override_enabled) {
set_mouse_mode_func(mouse_mode_override);
}
}
Input::MouseMode Input::get_mouse_mode() const {
return mouse_mode;
}
void Input::set_mouse_mode_override_enabled(bool p_enabled) {
if (p_enabled == mouse_mode_override_enabled) {
return;
}
mouse_mode_override_enabled = p_enabled;
if (p_enabled) {
set_mouse_mode_func(mouse_mode_override);
mouse_mode_override = get_mouse_mode_func();
} else {
set_mouse_mode_func(mouse_mode);
}
return get_mouse_mode_func();
}
void Input::set_mouse_mode_override(MouseMode p_mode) {
ERR_FAIL_INDEX((int)p_mode, 5);
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
set_mouse_mode_override_func(p_mode);
}
if (p_mode == mouse_mode_override) {
return;
}
Input::MouseMode Input::get_mouse_mode_override() const {
return get_mouse_mode_override_func();
}
if (mouse_mode_override_enabled) {
set_mouse_mode_func(p_mode);
mouse_mode_override = get_mouse_mode_func();
}
void Input::set_mouse_mode_override_enabled(bool p_override_enabled) {
set_mouse_mode_override_enabled_func(p_override_enabled);
}
bool Input::is_mouse_mode_override_enabled() {
return is_mouse_mode_override_enabled_func();
}
void Input::_bind_methods() {
@ -199,6 +181,7 @@ void Input::_bind_methods() {
BIND_ENUM_CONSTANT(MOUSE_MODE_CAPTURED);
BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED);
BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED_HIDDEN);
BIND_ENUM_CONSTANT(MOUSE_MODE_MAX);
BIND_ENUM_CONSTANT(CURSOR_ARROW);
BIND_ENUM_CONSTANT(CURSOR_IBEAM);

View File

@ -47,12 +47,14 @@ class Input : public Object {
static constexpr uint64_t MAX_EVENT = 32;
public:
// Keep synced with "DisplayServer::MouseMode" enum.
enum MouseMode {
MOUSE_MODE_VISIBLE,
MOUSE_MODE_HIDDEN,
MOUSE_MODE_CAPTURED,
MOUSE_MODE_CONFINED,
MOUSE_MODE_CONFINED_HIDDEN,
MOUSE_MODE_MAX,
};
#undef CursorShape
@ -105,10 +107,6 @@ private:
bool legacy_just_pressed_behavior = false;
bool disable_input = false;
MouseMode mouse_mode = MOUSE_MODE_VISIBLE;
bool mouse_mode_override_enabled = false;
MouseMode mouse_mode_override = MOUSE_MODE_VISIBLE;
struct ActionState {
uint64_t pressed_physics_frame = UINT64_MAX;
uint64_t pressed_process_frame = UINT64_MAX;
@ -268,6 +266,10 @@ private:
static void (*set_mouse_mode_func)(MouseMode);
static MouseMode (*get_mouse_mode_func)();
static void (*set_mouse_mode_override_func)(MouseMode);
static MouseMode (*get_mouse_mode_override_func)();
static void (*set_mouse_mode_override_enabled_func)(bool);
static bool (*is_mouse_mode_override_enabled_func)();
static void (*warp_mouse_func)(const Vector2 &p_position);
static CursorShape (*get_current_cursor_shape_func)();
@ -286,8 +288,10 @@ protected:
public:
void set_mouse_mode(MouseMode p_mode);
MouseMode get_mouse_mode() const;
void set_mouse_mode_override_enabled(bool p_enabled);
void set_mouse_mode_override(MouseMode p_mode);
MouseMode get_mouse_mode_override() const;
void set_mouse_mode_override_enabled(bool p_override_enabled);
bool is_mouse_mode_override_enabled();
#ifdef TOOLS_ENABLED
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;

View File

@ -1968,6 +1968,9 @@
<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="MOUSE_MODE_MAX" value="5" enum="MouseMode">
Max value of the [enum MouseMode].
</constant>
<constant name="SCREEN_WITH_MOUSE_FOCUS" value="-4">
Represents the screen containing the mouse pointer.
[b]Note:[/b] On Linux (Wayland), this constant always represents the screen at index [code]0[/code].

View File

@ -464,6 +464,9 @@
<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="MOUSE_MODE_MAX" value="5" enum="MouseMode">
Max value of the [enum MouseMode].
</constant>
<constant name="CURSOR_ARROW" value="0" enum="CursorShape">
Arrow cursor. Standard, default pointing cursor.
</constant>

View File

@ -771,33 +771,68 @@ void DisplayServerAndroid::process_gyroscope(const Vector3 &p_gyroscope) {
Input::get_singleton()->set_gyroscope(p_gyroscope);
}
void DisplayServerAndroid::mouse_set_mode(MouseMode p_mode) {
void DisplayServerAndroid::_mouse_update_mode() {
MouseMode wanted_mouse_mode = mouse_mode_override_enabled
? mouse_mode_override
: mouse_mode_base;
if (!OS_Android::get_singleton()->get_godot_java()->get_godot_view()->can_update_pointer_icon() || !OS_Android::get_singleton()->get_godot_java()->get_godot_view()->can_capture_pointer()) {
return;
}
if (mouse_mode == p_mode) {
if (mouse_mode == wanted_mouse_mode) {
return;
}
if (p_mode == MouseMode::MOUSE_MODE_HIDDEN) {
if (wanted_mouse_mode == MouseMode::MOUSE_MODE_HIDDEN) {
OS_Android::get_singleton()->get_godot_java()->get_godot_view()->set_pointer_icon(CURSOR_TYPE_NULL);
} else {
cursor_set_shape(cursor_shape);
}
if (p_mode == MouseMode::MOUSE_MODE_CAPTURED) {
if (wanted_mouse_mode == MouseMode::MOUSE_MODE_CAPTURED) {
OS_Android::get_singleton()->get_godot_java()->get_godot_view()->request_pointer_capture();
} else {
OS_Android::get_singleton()->get_godot_java()->get_godot_view()->release_pointer_capture();
}
mouse_mode = p_mode;
mouse_mode = wanted_mouse_mode;
}
void DisplayServerAndroid::mouse_set_mode(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_base) {
return;
}
mouse_mode_base = p_mode;
_mouse_update_mode();
}
DisplayServer::MouseMode DisplayServerAndroid::mouse_get_mode() const {
return mouse_mode;
}
void DisplayServerAndroid::mouse_set_mode_override(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_override) {
return;
}
mouse_mode_override = p_mode;
_mouse_update_mode();
}
DisplayServer::MouseMode DisplayServerAndroid::mouse_get_mode_override() const {
return mouse_mode_override;
}
void DisplayServerAndroid::mouse_set_mode_override_enabled(bool p_override_enabled) {
mouse_mode_override_enabled = p_override_enabled;
_mouse_update_mode();
}
bool DisplayServerAndroid::mouse_is_mode_override_enabled() const {
return mouse_mode_override_enabled;
}
Point2i DisplayServerAndroid::mouse_get_position() const {
return Input::get_singleton()->get_mouse_position();
}

View File

@ -66,6 +66,10 @@ class DisplayServerAndroid : public DisplayServer {
};
const int CURSOR_TYPE_NULL = 0;
MouseMode mouse_mode = MouseMode::MOUSE_MODE_VISIBLE;
MouseMode mouse_mode_base = MouseMode::MOUSE_MODE_VISIBLE;
MouseMode mouse_mode_override = MouseMode::MOUSE_MODE_VISIBLE;
bool mouse_mode_override_enabled = false;
void _mouse_update_mode();
bool keep_screen_on;
bool swap_buffers_flag;
@ -228,6 +232,10 @@ public:
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
virtual void mouse_set_mode_override(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode_override() const override;
virtual void mouse_set_mode_override_enabled(bool p_override_enabled) override;
virtual bool mouse_is_mode_override_enabled() const override;
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
static Vector<String> get_rendering_drivers_func();

View File

@ -325,20 +325,24 @@ void DisplayServerWayland::beep() const {
wayland_thread.beep();
}
void DisplayServerWayland::mouse_set_mode(MouseMode p_mode) {
if (p_mode == mouse_mode) {
void DisplayServerWayland::_mouse_update_mode() {
MouseMode wanted_mouse_mode = mouse_mode_override_enabled
? mouse_mode_override
: mouse_mode_base;
if (wanted_mouse_mode == mouse_mode) {
return;
}
MutexLock mutex_lock(wayland_thread.mutex);
bool show_cursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED);
bool show_cursor = (wanted_mouse_mode == MOUSE_MODE_VISIBLE || wanted_mouse_mode == MOUSE_MODE_CONFINED);
wayland_thread.cursor_set_visible(show_cursor);
WaylandThread::PointerConstraint constraint = WaylandThread::PointerConstraint::NONE;
switch (p_mode) {
switch (wanted_mouse_mode) {
case DisplayServer::MOUSE_MODE_CAPTURED: {
constraint = WaylandThread::PointerConstraint::LOCKED;
} break;
@ -354,13 +358,47 @@ void DisplayServerWayland::mouse_set_mode(MouseMode p_mode) {
wayland_thread.pointer_set_constraint(constraint);
mouse_mode = p_mode;
mouse_mode = wanted_mouse_mode;
}
void DisplayServerWayland::mouse_set_mode(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_base) {
return;
}
mouse_mode_base = p_mode;
_mouse_update_mode();
}
DisplayServerWayland::MouseMode DisplayServerWayland::mouse_get_mode() const {
return mouse_mode;
}
void DisplayServerWayland::mouse_set_mode_override(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_override) {
return;
}
mouse_mode_override = p_mode;
_mouse_update_mode();
}
DisplayServerWayland::MouseMode DisplayServerWayland::mouse_get_mode_override() const {
return mouse_mode_override;
}
void DisplayServerWayland::mouse_set_mode_override_enabled(bool p_override_enabled) {
if (p_override_enabled == mouse_mode_override_enabled) {
return;
}
mouse_mode_override_enabled = p_override_enabled;
_mouse_update_mode();
}
bool DisplayServerWayland::mouse_is_mode_override_enabled() const {
return mouse_mode_override_enabled;
}
// NOTE: This is hacked together (and not guaranteed to work in the first place)
// as for some reason the there's no proper way to ask the compositor to warp
// the pointer, although, at the time of writing, there's a proposal for a

View File

@ -113,6 +113,10 @@ class DisplayServerWayland : public DisplayServer {
CursorShape cursor_shape = CURSOR_ARROW;
DisplayServer::MouseMode mouse_mode = DisplayServer::MOUSE_MODE_VISIBLE;
DisplayServer::MouseMode mouse_mode_base = MOUSE_MODE_VISIBLE;
DisplayServer::MouseMode mouse_mode_override = MOUSE_MODE_VISIBLE;
bool mouse_mode_override_enabled = false;
void _mouse_update_mode();
HashMap<CursorShape, CustomCursor> custom_cursors;
@ -191,6 +195,10 @@ public:
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
virtual void mouse_set_mode_override(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode_override() const override;
virtual void mouse_set_mode_override_enabled(bool p_override_enabled) override;
virtual bool mouse_is_mode_override_enabled() const override;
virtual void warp_mouse(const Point2i &p_to) override;
virtual Point2i mouse_get_position() const override;

View File

@ -417,10 +417,14 @@ void DisplayServerX11::beep() const {
XBell(x11_display, 0);
}
void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
void DisplayServerX11::_mouse_update_mode() {
_THREAD_SAFE_METHOD_
if (p_mode == mouse_mode) {
MouseMode wanted_mouse_mode = mouse_mode_override_enabled
? mouse_mode_override
: mouse_mode_base;
if (wanted_mouse_mode == mouse_mode) {
return;
}
@ -429,7 +433,7 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
}
// The only modes that show a cursor are VISIBLE and CONFINED
bool show_cursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED);
bool show_cursor = (wanted_mouse_mode == MOUSE_MODE_VISIBLE || wanted_mouse_mode == MOUSE_MODE_CONFINED);
bool previously_shown = (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED);
if (show_cursor && !previously_shown) {
@ -450,7 +454,7 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
XDefineCursor(x11_display, E.value.x11_window, null_cursor); // hide cursor
}
}
mouse_mode = p_mode;
mouse_mode = wanted_mouse_mode;
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
//flush pending motion events
@ -484,10 +488,44 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
XFlush(x11_display);
}
void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_base) {
return;
}
mouse_mode_base = p_mode;
_mouse_update_mode();
}
DisplayServerX11::MouseMode DisplayServerX11::mouse_get_mode() const {
return mouse_mode;
}
void DisplayServerX11::mouse_set_mode_override(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_override) {
return;
}
mouse_mode_override = p_mode;
_mouse_update_mode();
}
DisplayServerX11::MouseMode DisplayServerX11::mouse_get_mode_override() const {
return mouse_mode_override;
}
void DisplayServerX11::mouse_set_mode_override_enabled(bool p_override_enabled) {
if (p_override_enabled == mouse_mode_override_enabled) {
return;
}
mouse_mode_override_enabled = p_override_enabled;
_mouse_update_mode();
}
bool DisplayServerX11::mouse_is_mode_override_enabled() const {
return mouse_mode_override_enabled;
}
void DisplayServerX11::warp_mouse(const Point2i &p_position) {
_THREAD_SAFE_METHOD_

View File

@ -297,6 +297,11 @@ class DisplayServerX11 : public DisplayServer {
void _flush_mouse_motion();
MouseMode mouse_mode = MOUSE_MODE_VISIBLE;
MouseMode mouse_mode_base = MOUSE_MODE_VISIBLE;
MouseMode mouse_mode_override = MOUSE_MODE_VISIBLE;
bool mouse_mode_override_enabled = false;
void _mouse_update_mode();
Point2i center;
void _handle_key_event(WindowID p_window, XKeyEvent *p_event, LocalVector<XEvent> &p_events, uint32_t &p_event_index, bool p_echo = false);
@ -424,6 +429,10 @@ public:
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
virtual void mouse_set_mode_override(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode_override() const override;
virtual void mouse_set_mode_override_enabled(bool p_override_enabled) override;
virtual bool mouse_is_mode_override_enabled() const override;
virtual void warp_mouse(const Point2i &p_position) override;
virtual Point2i mouse_get_position() const override;

View File

@ -169,6 +169,10 @@ private:
CGEventSourceRef event_source;
MouseMode mouse_mode = MOUSE_MODE_VISIBLE;
MouseMode mouse_mode_base = MOUSE_MODE_VISIBLE;
MouseMode mouse_mode_override = MOUSE_MODE_VISIBLE;
bool mouse_mode_override_enabled = false;
void _mouse_update_mode();
bool drop_events = false;
bool in_dispatch_input_event = false;
@ -306,6 +310,10 @@ public:
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
virtual void mouse_set_mode_override(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode_override() const override;
virtual void mouse_set_mode_override_enabled(bool p_override_enabled) override;
virtual bool mouse_is_mode_override_enabled() const override;
bool update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp);
virtual void warp_mouse(const Point2i &p_position) override;

View File

@ -1264,10 +1264,14 @@ Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description
return OK;
}
void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
void DisplayServerMacOS::_mouse_update_mode() {
_THREAD_SAFE_METHOD_
if (p_mode == mouse_mode) {
MouseMode wanted_mouse_mode = mouse_mode_override_enabled
? mouse_mode_override
: mouse_mode_base;
if (wanted_mouse_mode == mouse_mode) {
return;
}
@ -1277,7 +1281,7 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
}
WindowData &wd = windows[window_id];
bool show_cursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED);
bool show_cursor = (wanted_mouse_mode == MOUSE_MODE_VISIBLE || wanted_mouse_mode == MOUSE_MODE_CONFINED);
bool previously_shown = (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED);
if (show_cursor && !previously_shown) {
@ -1285,7 +1289,7 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
mouse_enter_window(window_id);
}
if (p_mode == MOUSE_MODE_CAPTURED) {
if (wanted_mouse_mode == MOUSE_MODE_CAPTURED) {
// Apple Docs state that the display parameter is not used.
// "This parameter is not used. By default, you may pass kCGDirectMainDisplay."
// https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/Quartz_Services_Ref/Reference/reference.html
@ -1299,17 +1303,17 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
NSPoint pointOnScreen = [[wd.window_view window] convertRectToScreen:pointInWindowRect].origin;
CGPoint lMouseWarpPos = { pointOnScreen.x, CGDisplayBounds(CGMainDisplayID()).size.height - pointOnScreen.y };
CGWarpMouseCursorPosition(lMouseWarpPos);
} else if (p_mode == MOUSE_MODE_HIDDEN) {
} else if (wanted_mouse_mode == MOUSE_MODE_HIDDEN) {
if (previously_shown) {
CGDisplayHideCursor(kCGDirectMainDisplay);
}
[wd.window_object setMovable:YES];
CGAssociateMouseAndMouseCursorPosition(true);
} else if (p_mode == MOUSE_MODE_CONFINED) {
} else if (wanted_mouse_mode == MOUSE_MODE_CONFINED) {
CGDisplayShowCursor(kCGDirectMainDisplay);
[wd.window_object setMovable:NO];
CGAssociateMouseAndMouseCursorPosition(false);
} else if (p_mode == MOUSE_MODE_CONFINED_HIDDEN) {
} else if (wanted_mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
if (previously_shown) {
CGDisplayHideCursor(kCGDirectMainDisplay);
}
@ -1324,17 +1328,51 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
last_warp = [[NSProcessInfo processInfo] systemUptime];
ignore_warp = true;
warp_events.clear();
mouse_mode = p_mode;
mouse_mode = wanted_mouse_mode;
if (show_cursor) {
cursor_update_shape();
}
}
void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_base) {
return;
}
mouse_mode_base = p_mode;
_mouse_update_mode();
}
DisplayServer::MouseMode DisplayServerMacOS::mouse_get_mode() const {
return mouse_mode;
}
void DisplayServerMacOS::mouse_set_mode_override(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_override) {
return;
}
mouse_mode_override = p_mode;
_mouse_update_mode();
}
DisplayServer::MouseMode DisplayServerMacOS::mouse_get_mode_override() const {
return mouse_mode_override;
}
void DisplayServerMacOS::mouse_set_mode_override_enabled(bool p_override_enabled) {
if (p_override_enabled == mouse_mode_override_enabled) {
return;
}
mouse_mode_override_enabled = p_override_enabled;
_mouse_update_mode();
}
bool DisplayServerMacOS::mouse_is_mode_override_enabled() const {
return mouse_mode_override_enabled;
}
bool DisplayServerMacOS::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp) {
_THREAD_SAFE_METHOD_

View File

@ -550,26 +550,39 @@ void DisplayServerWeb::cursor_set_custom_image(const Ref<Resource> &p_cursor, Cu
}
// Mouse mode
void DisplayServerWeb::mouse_set_mode(MouseMode p_mode) {
ERR_FAIL_COND_MSG(p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN, "MOUSE_MODE_CONFINED is not supported for the Web platform.");
if (p_mode == mouse_get_mode()) {
void DisplayServerWeb::_mouse_update_mode() {
MouseMode wanted_mouse_mode = mouse_mode_override_enabled
? mouse_mode_override
: mouse_mode_base;
ERR_FAIL_COND_MSG(wanted_mouse_mode == MOUSE_MODE_CONFINED || wanted_mouse_mode == MOUSE_MODE_CONFINED_HIDDEN, "MOUSE_MODE_CONFINED is not supported for the Web platform.");
if (wanted_mouse_mode == mouse_get_mode()) {
return;
}
if (p_mode == MOUSE_MODE_VISIBLE) {
if (wanted_mouse_mode == MOUSE_MODE_VISIBLE) {
godot_js_display_cursor_set_visible(1);
godot_js_display_cursor_lock_set(0);
} else if (p_mode == MOUSE_MODE_HIDDEN) {
} else if (wanted_mouse_mode == MOUSE_MODE_HIDDEN) {
godot_js_display_cursor_set_visible(0);
godot_js_display_cursor_lock_set(0);
} else if (p_mode == MOUSE_MODE_CAPTURED) {
} else if (wanted_mouse_mode == MOUSE_MODE_CAPTURED) {
godot_js_display_cursor_set_visible(1);
godot_js_display_cursor_lock_set(1);
}
}
void DisplayServerWeb::mouse_set_mode(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_base) {
return;
}
mouse_mode_base = p_mode;
_mouse_update_mode();
}
DisplayServer::MouseMode DisplayServerWeb::mouse_get_mode() const {
if (godot_js_display_cursor_is_hidden()) {
return MOUSE_MODE_HIDDEN;
@ -581,6 +594,31 @@ DisplayServer::MouseMode DisplayServerWeb::mouse_get_mode() const {
return MOUSE_MODE_VISIBLE;
}
void DisplayServerWeb::mouse_set_mode_override(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_override) {
return;
}
mouse_mode_override = p_mode;
_mouse_update_mode();
}
DisplayServer::MouseMode DisplayServerWeb::mouse_get_mode_override() const {
return mouse_mode_override;
}
void DisplayServerWeb::mouse_set_mode_override_enabled(bool p_override_enabled) {
if (p_override_enabled == mouse_mode_override_enabled) {
return;
}
mouse_mode_override_enabled = p_override_enabled;
_mouse_update_mode();
}
bool DisplayServerWeb::mouse_is_mode_override_enabled() const {
return mouse_mode_override_enabled;
}
Point2i DisplayServerWeb::mouse_get_position() const {
return Input::get_singleton()->get_mouse_position();
}

View File

@ -106,6 +106,11 @@ private:
bool tts = false;
NativeMenu *native_menu = nullptr;
MouseMode mouse_mode_base = MOUSE_MODE_VISIBLE;
MouseMode mouse_mode_override = MOUSE_MODE_VISIBLE;
bool mouse_mode_override_enabled = false;
void _mouse_update_mode();
// utilities
static void dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod, Key p_keycode);
static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape);
@ -184,6 +189,11 @@ public:
// mouse
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
virtual void mouse_set_mode_override(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode_override() const override;
virtual void mouse_set_mode_override_enabled(bool p_override_enabled) override;
virtual bool mouse_is_mode_override_enabled() const override;
virtual Point2i mouse_get_position() const override;
// ime

View File

@ -796,23 +796,61 @@ void DisplayServerWindows::beep() const {
MessageBeep(MB_OK);
}
void DisplayServerWindows::mouse_set_mode(MouseMode p_mode) {
void DisplayServerWindows::_mouse_update_mode() {
_THREAD_SAFE_METHOD_
if (mouse_mode == p_mode) {
MouseMode wanted_mouse_mode = mouse_mode_override_enabled
? mouse_mode_override
: mouse_mode_base;
if (mouse_mode == wanted_mouse_mode) {
// Already in the same mode; do nothing.
return;
}
mouse_mode = p_mode;
mouse_mode = wanted_mouse_mode;
_set_mouse_mode_impl(p_mode);
_set_mouse_mode_impl(wanted_mouse_mode);
}
void DisplayServerWindows::mouse_set_mode(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_base) {
return;
}
mouse_mode_base = p_mode;
_mouse_update_mode();
}
DisplayServer::MouseMode DisplayServerWindows::mouse_get_mode() const {
return mouse_mode;
}
void DisplayServerWindows::mouse_set_mode_override(MouseMode p_mode) {
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
if (p_mode == mouse_mode_override) {
return;
}
mouse_mode_override = p_mode;
_mouse_update_mode();
}
DisplayServer::MouseMode DisplayServerWindows::mouse_get_mode_override() const {
return mouse_mode_override;
}
void DisplayServerWindows::mouse_set_mode_override_enabled(bool p_override_enabled) {
if (p_override_enabled == mouse_mode_override_enabled) {
return;
}
mouse_mode_override_enabled = p_override_enabled;
_mouse_update_mode();
}
bool DisplayServerWindows::mouse_is_mode_override_enabled() const {
return mouse_mode_override_enabled;
}
void DisplayServerWindows::warp_mouse(const Point2i &p_position) {
_THREAD_SAFE_METHOD_

View File

@ -620,6 +620,10 @@ class DisplayServerWindows : public DisplayServer {
void _get_window_style(bool p_main_window, bool p_initialized, bool p_fullscreen, bool p_multiwindow_fs, bool p_borderless, bool p_resizable, bool p_minimized, bool p_maximized, bool p_maximized_fs, bool p_no_activate_focus, bool p_embed_child, DWORD &r_style, DWORD &r_style_ex);
MouseMode mouse_mode;
MouseMode mouse_mode_base = MOUSE_MODE_VISIBLE;
MouseMode mouse_mode_override = MOUSE_MODE_VISIBLE;
bool mouse_mode_override_enabled = false;
void _mouse_update_mode();
int restore_mouse_trails = 0;
bool use_raw_input = false;
@ -715,6 +719,10 @@ public:
virtual void mouse_set_mode(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode() const override;
virtual void mouse_set_mode_override(MouseMode p_mode) override;
virtual MouseMode mouse_get_mode_override() const override;
virtual void mouse_set_mode_override_enabled(bool p_override_enabled) override;
virtual bool mouse_is_mode_override_enabled() const override;
virtual void warp_mouse(const Point2i &p_position) override;
virtual Point2i mouse_get_position() const override;

View File

@ -501,6 +501,22 @@ DisplayServer::MouseMode DisplayServer::mouse_get_mode() const {
return MOUSE_MODE_VISIBLE;
}
void DisplayServer::mouse_set_mode_override(MouseMode p_mode) {
WARN_PRINT("Mouse is not supported by this display server.");
}
DisplayServer::MouseMode DisplayServer::mouse_get_mode_override() const {
return MOUSE_MODE_VISIBLE;
}
void DisplayServer::mouse_set_mode_override_enabled(bool p_override_enabled) {
WARN_PRINT("Mouse is not supported by this display server.");
}
bool DisplayServer::mouse_is_mode_override_enabled() const {
return false;
}
void DisplayServer::warp_mouse(const Point2i &p_position) {
}
@ -1098,6 +1114,7 @@ void DisplayServer::_bind_methods() {
BIND_ENUM_CONSTANT(MOUSE_MODE_CAPTURED);
BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED);
BIND_ENUM_CONSTANT(MOUSE_MODE_CONFINED_HIDDEN);
BIND_ENUM_CONSTANT(MOUSE_MODE_MAX);
BIND_CONSTANT(SCREEN_WITH_MOUSE_FOCUS);
BIND_CONSTANT(SCREEN_WITH_KEYBOARD_FOCUS);
@ -1266,6 +1283,22 @@ Input::MouseMode DisplayServer::_input_get_mouse_mode() {
return Input::MouseMode(singleton->mouse_get_mode());
}
void DisplayServer::_input_set_mouse_mode_override(Input::MouseMode p_mode) {
singleton->mouse_set_mode_override(MouseMode(p_mode));
}
Input::MouseMode DisplayServer::_input_get_mouse_mode_override() {
return Input::MouseMode(singleton->mouse_get_mode_override());
}
void DisplayServer::_input_set_mouse_mode_override_enabled(bool p_enabled) {
singleton->mouse_set_mode_override_enabled(p_enabled);
}
bool DisplayServer::_input_is_mouse_mode_override_enabled() {
return singleton->mouse_is_mode_override_enabled();
}
void DisplayServer::_input_warp(const Vector2 &p_to_pos) {
singleton->warp_mouse(p_to_pos);
}
@ -1347,6 +1380,10 @@ DisplayServer::DisplayServer() {
singleton = this;
Input::set_mouse_mode_func = _input_set_mouse_mode;
Input::get_mouse_mode_func = _input_get_mouse_mode;
Input::set_mouse_mode_override_func = _input_set_mouse_mode_override;
Input::get_mouse_mode_override_func = _input_get_mouse_mode_override;
Input::set_mouse_mode_override_enabled_func = _input_set_mouse_mode_override_enabled;
Input::is_mouse_mode_override_enabled_func = _input_is_mouse_mode_override_enabled;
Input::warp_mouse_func = _input_warp;
Input::get_current_cursor_shape_func = _input_get_current_cursor_shape;
Input::set_custom_mouse_cursor_func = _input_set_custom_mouse_cursor_func;

View File

@ -98,6 +98,10 @@ public:
private:
static void _input_set_mouse_mode(Input::MouseMode p_mode);
static Input::MouseMode _input_get_mouse_mode();
static void _input_set_mouse_mode_override(Input::MouseMode p_mode);
static Input::MouseMode _input_get_mouse_mode_override();
static void _input_set_mouse_mode_override_enabled(bool p_enabled);
static bool _input_is_mouse_mode_override_enabled();
static void _input_warp(const Vector2 &p_to_pos);
static Input::CursorShape _input_get_current_cursor_shape();
static void _input_set_custom_mouse_cursor_func(const Ref<Resource> &, Input::CursorShape, const Vector2 &p_hotspot);
@ -275,15 +279,20 @@ public:
static void set_early_window_clear_color_override(bool p_enabled, Color p_color = Color(0, 0, 0, 0));
enum MouseMode {
MOUSE_MODE_VISIBLE,
MOUSE_MODE_HIDDEN,
MOUSE_MODE_CAPTURED,
MOUSE_MODE_CONFINED,
MOUSE_MODE_CONFINED_HIDDEN,
MOUSE_MODE_VISIBLE = Input::MOUSE_MODE_VISIBLE,
MOUSE_MODE_HIDDEN = Input::MOUSE_MODE_HIDDEN,
MOUSE_MODE_CAPTURED = Input::MOUSE_MODE_CAPTURED,
MOUSE_MODE_CONFINED = Input::MOUSE_MODE_CONFINED,
MOUSE_MODE_CONFINED_HIDDEN = Input::MOUSE_MODE_CONFINED_HIDDEN,
MOUSE_MODE_MAX = Input::MOUSE_MODE_MAX,
};
virtual void mouse_set_mode(MouseMode p_mode);
virtual MouseMode mouse_get_mode() const;
virtual void mouse_set_mode_override(MouseMode p_mode);
virtual MouseMode mouse_get_mode_override() const;
virtual void mouse_set_mode_override_enabled(bool p_override_enabled);
virtual bool mouse_is_mode_override_enabled() const;
virtual void warp_mouse(const Point2i &p_position);
virtual Point2i mouse_get_position() const;

View File

@ -170,6 +170,8 @@ public:
void tts_stop() override {}
void mouse_set_mode(MouseMode p_mode) override {}
void mouse_set_mode_override(MouseMode p_mode) override {}
void mouse_set_mode_override_enabled(bool p_override_enabled) override {}
Point2i mouse_get_position() const override { return Point2i(); }
void clipboard_set(const String &p_text) override {}
void clipboard_set_primary(const String &p_text) override {}