Ensure embedded mode works again
Also implemented application in/out notifications in X11.
This commit is contained in:
parent
719609522a
commit
239942cfef
@ -2339,6 +2339,24 @@ void DisplayServerX11::_send_window_event(const WindowData &wd, WindowEvent p_ev
|
|||||||
void DisplayServerX11::process_events() {
|
void DisplayServerX11::process_events() {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
if (app_focused) {
|
||||||
|
//verify that one of the windows has focus, else send focus out notification
|
||||||
|
bool focus_found = false;
|
||||||
|
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
|
||||||
|
if (E->get().focused) {
|
||||||
|
focus_found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!focus_found) {
|
||||||
|
if (OS::get_singleton()->get_main_loop()) {
|
||||||
|
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
app_focused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
do_mouse_warp = false;
|
do_mouse_warp = false;
|
||||||
|
|
||||||
// Is the current mouse mode one where it needs to be grabbed.
|
// Is the current mouse mode one where it needs to be grabbed.
|
||||||
@ -2533,12 +2551,12 @@ void DisplayServerX11::process_events() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case NoExpose:
|
case NoExpose:
|
||||||
minimized = true;
|
windows[window_id].minimized = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VisibilityNotify: {
|
case VisibilityNotify: {
|
||||||
XVisibilityEvent *visibility = (XVisibilityEvent *)&event;
|
XVisibilityEvent *visibility = (XVisibilityEvent *)&event;
|
||||||
minimized = (visibility->state == VisibilityFullyObscured);
|
windows[window_id].minimized = (visibility->state == VisibilityFullyObscured);
|
||||||
} break;
|
} break;
|
||||||
case LeaveNotify: {
|
case LeaveNotify: {
|
||||||
if (!mouse_mode_grab) {
|
if (!mouse_mode_grab) {
|
||||||
@ -2552,10 +2570,8 @@ void DisplayServerX11::process_events() {
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
minimized = false;
|
windows[window_id].focused = true;
|
||||||
window_has_focus = true;
|
|
||||||
_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_IN);
|
_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_IN);
|
||||||
window_focused = true;
|
|
||||||
|
|
||||||
if (mouse_mode_grab) {
|
if (mouse_mode_grab) {
|
||||||
// Show and update the cursor if confined and the window regained focus.
|
// Show and update the cursor if confined and the window regained focus.
|
||||||
@ -2582,13 +2598,19 @@ void DisplayServerX11::process_events() {
|
|||||||
if (windows[window_id].xic) {
|
if (windows[window_id].xic) {
|
||||||
XSetICFocus(windows[window_id].xic);
|
XSetICFocus(windows[window_id].xic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!app_focused) {
|
||||||
|
if (OS::get_singleton()->get_main_loop()) {
|
||||||
|
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
|
||||||
|
}
|
||||||
|
app_focused = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
window_has_focus = false;
|
windows[window_id].focused = false;
|
||||||
Input::get_singleton()->release_pressed_events();
|
Input::get_singleton()->release_pressed_events();
|
||||||
_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT);
|
_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT);
|
||||||
window_focused = false;
|
|
||||||
|
|
||||||
if (mouse_mode_grab) {
|
if (mouse_mode_grab) {
|
||||||
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
|
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
|
||||||
@ -2727,7 +2749,7 @@ void DisplayServerX11::process_events() {
|
|||||||
Point2i new_center = pos;
|
Point2i new_center = pos;
|
||||||
pos = last_mouse_pos + xi.relative_motion;
|
pos = last_mouse_pos + xi.relative_motion;
|
||||||
center = new_center;
|
center = new_center;
|
||||||
do_mouse_warp = window_has_focus; // warp the cursor if we're focused in
|
do_mouse_warp = windows[window_id].focused; // warp the cursor if we're focused in
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!last_mouse_pos_valid) {
|
if (!last_mouse_pos_valid) {
|
||||||
@ -2787,7 +2809,7 @@ void DisplayServerX11::process_events() {
|
|||||||
// Don't propagate the motion event unless we have focus
|
// Don't propagate the motion event unless we have focus
|
||||||
// this is so that the relative motion doesn't get messed up
|
// this is so that the relative motion doesn't get messed up
|
||||||
// after we regain focus.
|
// after we regain focus.
|
||||||
if (window_has_focus || !mouse_mode_grab) {
|
if (windows[window_id].focused || !mouse_mode_grab) {
|
||||||
Input::get_singleton()->accumulate_input_event(mm);
|
Input::get_singleton()->accumulate_input_event(mm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3764,8 +3786,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||||||
|
|
||||||
requested = None;
|
requested = None;
|
||||||
|
|
||||||
window_has_focus = true; // Set focus to true at init
|
|
||||||
|
|
||||||
/*if (p_desired.layered) {
|
/*if (p_desired.layered) {
|
||||||
set_window_per_pixel_transparency_enabled(true);
|
set_window_per_pixel_transparency_enabled(true);
|
||||||
}*/
|
}*/
|
||||||
|
@ -139,6 +139,8 @@ class DisplayServerX11 : public DisplayServer {
|
|||||||
bool borderless = false;
|
bool borderless = false;
|
||||||
bool resize_disabled = false;
|
bool resize_disabled = false;
|
||||||
Vector2i last_position_before_fs;
|
Vector2i last_position_before_fs;
|
||||||
|
bool focused = false;
|
||||||
|
bool minimized = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Map<WindowID, WindowData> windows;
|
Map<WindowID, WindowData> windows;
|
||||||
@ -164,6 +166,7 @@ class DisplayServerX11 : public DisplayServer {
|
|||||||
uint64_t last_click_ms;
|
uint64_t last_click_ms;
|
||||||
int last_click_button_index;
|
int last_click_button_index;
|
||||||
uint32_t last_button_state;
|
uint32_t last_button_state;
|
||||||
|
bool app_focused = false;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int opcode;
|
int opcode;
|
||||||
@ -195,8 +198,8 @@ class DisplayServerX11 : public DisplayServer {
|
|||||||
|
|
||||||
void _handle_key_event(WindowID p_window, XKeyEvent *p_event, bool p_echo = false);
|
void _handle_key_event(WindowID p_window, XKeyEvent *p_event, bool p_echo = false);
|
||||||
|
|
||||||
bool minimized;
|
//bool minimized;
|
||||||
bool window_has_focus;
|
//bool window_has_focus;
|
||||||
bool do_mouse_warp;
|
bool do_mouse_warp;
|
||||||
|
|
||||||
const char *cursor_theme;
|
const char *cursor_theme;
|
||||||
@ -210,7 +213,7 @@ class DisplayServerX11 : public DisplayServer {
|
|||||||
bool layered_window;
|
bool layered_window;
|
||||||
|
|
||||||
String rendering_driver;
|
String rendering_driver;
|
||||||
bool window_focused;
|
//bool window_focused;
|
||||||
//void set_wm_border(bool p_enabled);
|
//void set_wm_border(bool p_enabled);
|
||||||
void set_wm_fullscreen(bool p_enabled);
|
void set_wm_fullscreen(bool p_enabled);
|
||||||
void set_wm_above(bool p_enabled);
|
void set_wm_above(bool p_enabled);
|
||||||
|
@ -2913,6 +2913,10 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_can_consume_input_events()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_input_handled()) {
|
if (!is_input_handled()) {
|
||||||
get_tree()->_call_input_pause(input_group, "_input", ev, this); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
|
get_tree()->_call_input_pause(input_group, "_input", ev, this); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
|
||||||
}
|
}
|
||||||
@ -2926,7 +2930,7 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
|
|||||||
void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
|
void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
|
||||||
ERR_FAIL_COND(!is_inside_tree());
|
ERR_FAIL_COND(!is_inside_tree());
|
||||||
|
|
||||||
if (disable_input) {
|
if (disable_input || !_can_consume_input_events()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,6 +441,8 @@ private:
|
|||||||
bool _sub_windows_forward_input(const Ref<InputEvent> &p_event);
|
bool _sub_windows_forward_input(const Ref<InputEvent> &p_event);
|
||||||
SubWindowResize _sub_window_get_resize_margin(Window *p_subwindow, const Point2 &p_point);
|
SubWindowResize _sub_window_get_resize_margin(Window *p_subwindow, const Point2 &p_point);
|
||||||
|
|
||||||
|
virtual bool _can_consume_input_events() const { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _set_size(const Size2i &p_size, const Size2i &p_size_2d_override, const Rect2i &p_to_screen_rect, const Transform2D &p_stretch_transform, bool p_allocated);
|
void _set_size(const Size2i &p_size, const Size2i &p_size_2d_override, const Rect2i &p_to_screen_rect, const Transform2D &p_stretch_transform, bool p_allocated);
|
||||||
|
|
||||||
|
@ -874,6 +874,10 @@ void Window::child_controls_changed() {
|
|||||||
call_deferred("_update_child_controls");
|
call_deferred("_update_child_controls");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Window::_can_consume_input_events() const {
|
||||||
|
return exclusive_child == nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void Window::_window_input(const Ref<InputEvent> &p_ev) {
|
void Window::_window_input(const Ref<InputEvent> &p_ev) {
|
||||||
if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_ev.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_ev))) {
|
if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_ev.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_ev))) {
|
||||||
return; //avoid joy input on editor
|
return; //avoid joy input on editor
|
||||||
@ -890,10 +894,13 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) {
|
|||||||
if (exclusive_child != nullptr) {
|
if (exclusive_child != nullptr) {
|
||||||
exclusive_child->grab_focus();
|
exclusive_child->grab_focus();
|
||||||
|
|
||||||
return; //has an exclusive child, can't get events until child is closed
|
if (!is_embedding_subwindows()) { //not embedding, no need for event
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_signal(SceneStringNames::get_singleton()->window_input, p_ev);
|
emit_signal(SceneStringNames::get_singleton()->window_input, p_ev);
|
||||||
|
|
||||||
input(p_ev);
|
input(p_ev);
|
||||||
if (!is_input_handled()) {
|
if (!is_input_handled()) {
|
||||||
unhandled_input(p_ev);
|
unhandled_input(p_ev);
|
||||||
|
@ -130,6 +130,7 @@ private:
|
|||||||
void _window_drop_files(const Vector<String> &p_files);
|
void _window_drop_files(const Vector<String> &p_files);
|
||||||
void _rect_changed_callback(const Rect2i &p_callback);
|
void _rect_changed_callback(const Rect2i &p_callback);
|
||||||
void _event_callback(DisplayServer::WindowEvent p_event);
|
void _event_callback(DisplayServer::WindowEvent p_event);
|
||||||
|
virtual bool _can_consume_input_events() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Viewport *_get_embedder() const;
|
Viewport *_get_embedder() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user