summaryrefslogtreecommitdiff
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.cpp75
1 files changed, 50 insertions, 25 deletions
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 8fa8c64efe..a36fcabd91 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -670,17 +670,17 @@ void DisplayServerX11::_clipboard_transfer_ownership(Atom p_source, Window x11_w
int DisplayServerX11::get_screen_count() const {
_THREAD_SAFE_METHOD_
+ int count = 0;
// Using Xinerama Extension
int event_base, error_base;
- const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
- if (!ext_okay) {
- return 0;
+ if (XineramaQueryExtension(x11_display, &event_base, &error_base)) {
+ XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
+ XFree(xsi);
+ } else {
+ count = XScreenCount(x11_display);
}
- int count;
- XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
- XFree(xsi);
return count;
}
@@ -712,6 +712,19 @@ Rect2i DisplayServerX11::_screen_get_rect(int p_screen) const {
if (xsi) {
XFree(xsi);
}
+ } else {
+ int count = XScreenCount(x11_display);
+ if (p_screen < count) {
+ Window root = XRootWindow(x11_display, p_screen);
+ XWindowAttributes xwa;
+ XGetWindowAttributes(x11_display, root, &xwa);
+ rect.position.x = xwa.x;
+ rect.position.y = xwa.y;
+ rect.size.width = xwa.width;
+ rect.size.height = xwa.height;
+ } else {
+ ERR_PRINT("Invalid screen index: " + itos(p_screen) + "(count: " + itos(count) + ").");
+ }
}
return rect;
@@ -2130,7 +2143,7 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co
unsigned char *data = nullptr;
if (XGetWindowProperty(x11_display, wd.x11_window, prop, 0, sizeof(Hints), False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) {
if (data && (format == 32) && (len >= 5)) {
- borderless = !((Hints *)data)->decorations;
+ borderless = !(reinterpret_cast<Hints *>(data)->decorations);
}
if (data) {
XFree(data);
@@ -2162,7 +2175,7 @@ void DisplayServerX11::window_request_attention(WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
- WindowData &wd = windows[p_window];
+ const WindowData &wd = windows[p_window];
// Using EWMH -- Extended Window Manager Hints
//
// Sets the _NET_WM_STATE_DEMANDS_ATTENTION atom for WM_STATE
@@ -2188,7 +2201,7 @@ void DisplayServerX11::window_move_to_foreground(WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
- WindowData &wd = windows[p_window];
+ const WindowData &wd = windows[p_window];
XEvent xev;
Atom net_active_window = XInternAtom(x11_display, "_NET_ACTIVE_WINDOW", False);
@@ -2534,10 +2547,9 @@ DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display,
unsigned long bytes_after = 0;
unsigned char *ret = nullptr;
- int read_bytes = 1024;
-
// Keep trying to read the property until there are no bytes unread.
if (p_property != None) {
+ int read_bytes = 1024;
do {
if (ret != nullptr) {
XFree(ret);
@@ -2557,7 +2569,7 @@ DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display,
return p;
}
-static Atom pick_target_from_list(Display *p_display, Atom *p_list, int p_count) {
+static Atom pick_target_from_list(Display *p_display, const Atom *p_list, int p_count) {
static const char *target_type = "text/uri-list";
for (int i = 0; i < p_count; i++) {
@@ -3052,7 +3064,7 @@ void DisplayServerX11::_window_changed(XEvent *event) {
}
void DisplayServerX11::_dispatch_input_events(const Ref<InputEvent> &p_event) {
- ((DisplayServerX11 *)(get_singleton()))->_dispatch_input_event(p_event);
+ static_cast<DisplayServerX11 *>(get_singleton())->_dispatch_input_event(p_event);
}
void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) {
@@ -3062,7 +3074,7 @@ void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) {
Callable::CallError ce;
{
- List<WindowID>::Element *E = popup_list.front();
+ List<WindowID>::Element *E = popup_list.back();
if (E && Object::cast_to<InputEventKey>(*p_event)) {
// Redirect keyboard input to active popup.
if (windows.has(E->get())) {
@@ -3106,7 +3118,7 @@ void DisplayServerX11::_send_window_event(const WindowData &wd, WindowEvent p_ev
}
void DisplayServerX11::_poll_events_thread(void *ud) {
- DisplayServerX11 *display_server = (DisplayServerX11 *)ud;
+ DisplayServerX11 *display_server = static_cast<DisplayServerX11 *>(ud);
display_server->_poll_events();
}
@@ -3208,20 +3220,24 @@ Rect2i DisplayServerX11::window_get_popup_safe_rect(WindowID p_window) const {
}
void DisplayServerX11::popup_open(WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+
WindowData &wd = windows[p_window];
if (wd.is_popup) {
- // Close all popups, up to current popup parent, or every popup if new window is not transient.
+ // Find current popup parent, or root popup if new window is not transient.
+ List<WindowID>::Element *C = nullptr;
List<WindowID>::Element *E = popup_list.back();
while (E) {
if (wd.transient_parent != E->get() || wd.transient_parent == INVALID_WINDOW_ID) {
- _send_window_event(windows[E->get()], DisplayServerX11::WINDOW_EVENT_CLOSE_REQUEST);
- List<WindowID>::Element *F = E->prev();
- popup_list.erase(E);
- E = F;
+ C = E;
+ E = E->prev();
} else {
break;
}
}
+ if (C) {
+ _send_window_event(windows[C->get()], DisplayServerX11::WINDOW_EVENT_CLOSE_REQUEST);
+ }
time_since_popup = OS::get_singleton()->get_ticks_msec();
popup_list.push_back(p_window);
@@ -3229,16 +3245,22 @@ void DisplayServerX11::popup_open(WindowID p_window) {
}
void DisplayServerX11::popup_close(WindowID p_window) {
+ _THREAD_SAFE_METHOD_
+
List<WindowID>::Element *E = popup_list.find(p_window);
while (E) {
- _send_window_event(windows[E->get()], DisplayServerX11::WINDOW_EVENT_CLOSE_REQUEST);
List<WindowID>::Element *F = E->next();
+ WindowID win_id = E->get();
popup_list.erase(E);
+
+ _send_window_event(windows[win_id], DisplayServerX11::WINDOW_EVENT_CLOSE_REQUEST);
E = F;
}
}
void DisplayServerX11::mouse_process_popups() {
+ _THREAD_SAFE_METHOD_
+
if (popup_list.is_empty()) {
return;
}
@@ -3259,7 +3281,9 @@ void DisplayServerX11::mouse_process_popups() {
Vector2i pos = Vector2i(root_attrs.x + root_x, root_attrs.y + root_y);
if ((pos != last_mouse_monitor_pos) || (mask != last_mouse_monitor_mask)) {
if (((mask & Button1Mask) || (mask & Button2Mask) || (mask & Button3Mask) || (mask & Button4Mask) || (mask & Button5Mask))) {
+ List<WindowID>::Element *C = nullptr;
List<WindowID>::Element *E = popup_list.back();
+ // Find top popup to close.
while (E) {
// Popup window area.
Rect2i win_rect = Rect2i(window_get_position(E->get()), window_get_size(E->get()));
@@ -3270,12 +3294,13 @@ void DisplayServerX11::mouse_process_popups() {
} else if (safe_rect != Rect2i() && safe_rect.has_point(pos)) {
break;
} else {
- _send_window_event(windows[E->get()], DisplayServerX11::WINDOW_EVENT_CLOSE_REQUEST);
- List<WindowID>::Element *F = E->prev();
- popup_list.erase(E);
- E = F;
+ C = E;
+ E = E->prev();
}
}
+ if (C) {
+ _send_window_event(windows[C->get()], DisplayServerX11::WINDOW_EVENT_CLOSE_REQUEST);
+ }
}
}
last_mouse_monitor_mask = mask;