summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd/display_server_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd/display_server_x11.cpp')
-rw-r--r--platform/linuxbsd/display_server_x11.cpp36
1 files changed, 31 insertions, 5 deletions
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index cb4b0d745b..c9b951f4d9 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -410,7 +410,18 @@ void DisplayServerX11::mouse_warp_to_position(const Point2i &p_to) {
}
Point2i DisplayServerX11::mouse_get_position() const {
- return last_mouse_pos;
+ int root_x, root_y;
+ int win_x, win_y;
+ unsigned int mask_return;
+ Window window_returned;
+
+ Bool result = XQueryPointer(x11_display, RootWindow(x11_display, DefaultScreen(x11_display)), &window_returned,
+ &window_returned, &root_x, &root_y, &win_x, &win_y,
+ &mask_return);
+ if (result == True) {
+ return Point2i(root_x, root_y);
+ }
+ return Point2i();
}
Point2i DisplayServerX11::mouse_get_absolute_position() const {
@@ -718,6 +729,14 @@ ObjectID DisplayServerX11::window_get_attached_instance_id(WindowID p_window) co
}
DisplayServerX11::WindowID DisplayServerX11::get_window_at_screen_position(const Point2i &p_position) const {
+#warning This is an incorrect implementation, if windows overlap, it should return the topmost visible one or none if occluded by a foreign window
+
+ for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ Rect2i win_rect = Rect2i(window_get_position(E->key()), window_get_size(E->key()));
+ if (win_rect.has_point(p_position)) {
+ return E->key();
+ }
+ }
return INVALID_WINDOW_ID;
}
@@ -2345,15 +2364,22 @@ void DisplayServerX11::process_events() {
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
if (E->get().focused) {
focus_found = true;
+ break;
}
}
if (!focus_found) {
- if (OS::get_singleton()->get_main_loop()) {
- OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
- }
+ uint64_t delta = OS::get_singleton()->get_ticks_msec() - time_since_no_focus;
- app_focused = false;
+ if (delta > 250) {
+ //X11 can go between windows and have no focus for a while, when creating them or something else. Use this as safety to avoid unnecesary focus in/outs.
+ if (OS::get_singleton()->get_main_loop()) {
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
+ }
+ app_focused = false;
+ }
+ } else {
+ time_since_no_focus = OS::get_singleton()->get_ticks_msec();
}
}