Skip to content

Commit 0419c92

Browse files
committed
Merge pull request godotengine#104644 from bruvzg/macos_sync_mb
[macOS] Release keys and regenerate mouse events after native popup menu tracking.
2 parents f4425ae + d1edf66 commit 0419c92

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

platform/macos/display_server_macos.h

+1
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ class DisplayServerMacOS : public DisplayServer {
253253
void send_event(NSEvent *p_event);
254254
void send_window_event(const WindowData &p_wd, WindowEvent p_event);
255255
void release_pressed_events();
256+
void sync_mouse_state();
256257
void get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const;
257258
void update_mouse_pos(WindowData &p_wd, NSPoint p_location_in_window);
258259
void push_to_key_event_buffer(const KeyEvent &p_event);

platform/macos/display_server_macos.mm

+32
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,38 @@
681681
}
682682
}
683683

684+
void DisplayServerMacOS::sync_mouse_state() {
685+
_THREAD_SAFE_METHOD_
686+
if (Input::get_singleton()) {
687+
Vector2i pos = Input::get_singleton()->get_mouse_position();
688+
BitField<MouseButtonMask> in_mask = Input::get_singleton()->get_mouse_button_mask();
689+
BitField<MouseButtonMask> ds_mask = mouse_get_button_state();
690+
for (int btn = (int)MouseButton::LEFT; btn <= (int)MouseButton::MB_XBUTTON2; btn++) {
691+
MouseButtonMask mbm = mouse_button_to_mask(MouseButton(btn));
692+
if (in_mask.has_flag(mbm) && !ds_mask.has_flag(mbm)) {
693+
Ref<InputEventMouseButton> mb;
694+
mb.instantiate();
695+
mb->set_button_index(MouseButton(btn));
696+
mb->set_pressed(false);
697+
mb->set_position(pos);
698+
mb->set_global_position(pos);
699+
mb->set_button_mask(ds_mask);
700+
Input::get_singleton()->parse_input_event(mb);
701+
}
702+
if (!in_mask.has_flag(mbm) && ds_mask.has_flag(mbm)) {
703+
Ref<InputEventMouseButton> mb;
704+
mb.instantiate();
705+
mb->set_button_index(MouseButton(btn));
706+
mb->set_pressed(true);
707+
mb->set_position(pos);
708+
mb->set_global_position(pos);
709+
mb->set_button_mask(ds_mask);
710+
Input::get_singleton()->parse_input_event(mb);
711+
}
712+
}
713+
}
714+
}
715+
684716
void DisplayServerMacOS::get_key_modifier_state(unsigned int p_macos_state, Ref<InputEventWithModifiers> r_state) const {
685717
r_state->set_shift_pressed((p_macos_state & NSEventModifierFlagShift));
686718
r_state->set_ctrl_pressed((p_macos_state & NSEventModifierFlagControl));

platform/macos/native_menu_macos.mm

+3
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,9 @@
294294
position /= ds->screen_get_max_scale();
295295

296296
[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.
297+
298+
ds->release_pressed_events(); // Note: context menu block main loop and consume events, pressed keys and mouse buttons should be released manually.
299+
ds->sync_mouse_state();
297300
}
298301
}
299302

0 commit comments

Comments
 (0)