1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

[macOS] Release keys and regenerate mouse events after native popup menu tracking.

This commit is contained in:
Pāvels Nadtočajevs
2025-03-26 12:18:55 +02:00
parent 594d64ec24
commit d1edf66a13
3 changed files with 36 additions and 0 deletions

View File

@@ -253,6 +253,7 @@ public:
void send_event(NSEvent *p_event); void send_event(NSEvent *p_event);
void send_window_event(const WindowData &p_wd, WindowEvent p_event); void send_window_event(const WindowData &p_wd, WindowEvent p_event);
void release_pressed_events(); void release_pressed_events();
void sync_mouse_state();
void get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const; void get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const;
void update_mouse_pos(WindowData &p_wd, NSPoint p_location_in_window); void update_mouse_pos(WindowData &p_wd, NSPoint p_location_in_window);
void push_to_key_event_buffer(const KeyEvent &p_event); void push_to_key_event_buffer(const KeyEvent &p_event);

View File

@@ -681,6 +681,38 @@ void DisplayServerMacOS::release_pressed_events() {
} }
} }
void DisplayServerMacOS::sync_mouse_state() {
_THREAD_SAFE_METHOD_
if (Input::get_singleton()) {
Vector2i pos = Input::get_singleton()->get_mouse_position();
BitField<MouseButtonMask> in_mask = Input::get_singleton()->get_mouse_button_mask();
BitField<MouseButtonMask> ds_mask = mouse_get_button_state();
for (int btn = (int)MouseButton::LEFT; btn <= (int)MouseButton::MB_XBUTTON2; btn++) {
MouseButtonMask mbm = mouse_button_to_mask(MouseButton(btn));
if (in_mask.has_flag(mbm) && !ds_mask.has_flag(mbm)) {
Ref<InputEventMouseButton> mb;
mb.instantiate();
mb->set_button_index(MouseButton(btn));
mb->set_pressed(false);
mb->set_position(pos);
mb->set_global_position(pos);
mb->set_button_mask(ds_mask);
Input::get_singleton()->parse_input_event(mb);
}
if (!in_mask.has_flag(mbm) && ds_mask.has_flag(mbm)) {
Ref<InputEventMouseButton> mb;
mb.instantiate();
mb->set_button_index(MouseButton(btn));
mb->set_pressed(true);
mb->set_position(pos);
mb->set_global_position(pos);
mb->set_button_mask(ds_mask);
Input::get_singleton()->parse_input_event(mb);
}
}
}
}
void DisplayServerMacOS::get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const { void DisplayServerMacOS::get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const {
r_state->set_shift_pressed((p_macos_state & NSEventModifierFlagShift)); r_state->set_shift_pressed((p_macos_state & NSEventModifierFlagShift));
r_state->set_ctrl_pressed((p_macos_state & NSEventModifierFlagControl)); r_state->set_ctrl_pressed((p_macos_state & NSEventModifierFlagControl));

View File

@@ -294,6 +294,9 @@ void NativeMenuMacOS::popup(const RID &p_rid, const Vector2i &p_position) {
position /= ds->screen_get_max_scale(); position /= ds->screen_get_max_scale();
[md->menu popUpMenuPositioningItem:nil atLocation:NSMakePoint(position.x, position.y - 5) inView:nil]; // Menu vertical position doesn't include rounded corners, add `5` display pixels to better align it with Godot buttons. [md->menu popUpMenuPositioningItem:nil atLocation:NSMakePoint(position.x, position.y - 5) inView:nil]; // Menu vertical position doesn't include rounded corners, add `5` display pixels to better align it with Godot buttons.
ds->release_pressed_events(); // Note: context menu block main loop and consume events, pressed keys and mouse buttons should be released manually.
ds->sync_mouse_state();
} }
} }