summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp33
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h4
-rw-r--r--platform/macos/display_server_macos.h1
-rw-r--r--platform/macos/display_server_macos.mm12
-rw-r--r--platform/windows/display_server_windows.cpp17
-rw-r--r--platform/windows/display_server_windows.h1
6 files changed, 58 insertions, 10 deletions
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 10fd9972e3..a2c34bb874 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -1420,13 +1420,22 @@ void DisplayServerX11::window_set_mouse_passthrough(const Vector<Vector2> &p_reg
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
- const WindowData &wd = windows[p_window];
+ windows[p_window].mpath = p_region;
+ _update_window_mouse_passthrough(p_window);
+}
+
+void DisplayServerX11::_update_window_mouse_passthrough(WindowID p_window) {
+ ERR_FAIL_COND(!windows.has(p_window));
+
+ const Vector<Vector2> region_path = windows[p_window].mpath;
int event_base, error_base;
const Bool ext_okay = XShapeQueryExtension(x11_display, &event_base, &error_base);
if (ext_okay) {
Region region;
- if (p_region.size() == 0) {
+ if (windows[p_window].mpass) {
+ region = XCreateRegion();
+ } else if (region_path.size() == 0) {
region = XCreateRegion();
XRectangle rect;
rect.x = 0;
@@ -1435,15 +1444,15 @@ void DisplayServerX11::window_set_mouse_passthrough(const Vector<Vector2> &p_reg
rect.height = window_get_size_with_decorations(p_window).y;
XUnionRectWithRegion(&rect, region, region);
} else {
- XPoint *points = (XPoint *)memalloc(sizeof(XPoint) * p_region.size());
- for (int i = 0; i < p_region.size(); i++) {
- points[i].x = p_region[i].x;
- points[i].y = p_region[i].y;
+ XPoint *points = (XPoint *)memalloc(sizeof(XPoint) * region_path.size());
+ for (int i = 0; i < region_path.size(); i++) {
+ points[i].x = region_path[i].x;
+ points[i].y = region_path[i].y;
}
- region = XPolygonRegion(points, p_region.size(), EvenOddRule);
+ region = XPolygonRegion(points, region_path.size(), EvenOddRule);
memfree(points);
}
- XShapeCombineRegion(x11_display, wd.x11_window, ShapeInput, 0, 0, region, ShapeSet);
+ XShapeCombineRegion(x11_display, windows[p_window].x11_window, ShapeInput, 0, 0, region, ShapeSet);
XDestroyRegion(region);
}
}
@@ -2312,6 +2321,7 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
window_set_size(window_get_size(p_window), p_window);
wd.borderless = p_enabled;
+ _update_window_mouse_passthrough(p_window);
} break;
case WINDOW_FLAG_ALWAYS_ON_TOP: {
ERR_FAIL_COND_MSG(wd.transient_parent != INVALID_WINDOW_ID, "Can't make a window transient if the 'on top' flag is active.");
@@ -2345,6 +2355,10 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
case WINDOW_FLAG_NO_FOCUS: {
wd.no_focus = p_enabled;
} break;
+ case WINDOW_FLAG_MOUSE_PASSTHROUGH: {
+ wd.mpass = p_enabled;
+ _update_window_mouse_passthrough(p_window);
+ } break;
case WINDOW_FLAG_POPUP: {
XWindowAttributes xwa;
XSync(x11_display, False);
@@ -2398,6 +2412,9 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co
case WINDOW_FLAG_NO_FOCUS: {
return wd.no_focus;
} break;
+ case WINDOW_FLAG_MOUSE_PASSTHROUGH: {
+ return wd.mpass;
+ } break;
case WINDOW_FLAG_POPUP: {
return wd.is_popup;
} break;
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index 43a66f95b2..437766d953 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -149,6 +149,8 @@ class DisplayServerX11 : public DisplayServer {
Callable input_text_callback;
Callable drop_files_callback;
+ Vector<Vector2> mpath;
+
WindowID transient_parent = INVALID_WINDOW_ID;
HashSet<WindowID> transient_children;
@@ -169,6 +171,7 @@ class DisplayServerX11 : public DisplayServer {
bool maximized = false;
bool is_popup = false;
bool layered_window = false;
+ bool mpass = false;
Rect2i parent_safe_rect;
@@ -245,6 +248,7 @@ class DisplayServerX11 : public DisplayServer {
Atom _process_selection_request_target(Atom p_target, Window p_requestor, Atom p_property, Atom p_selection) const;
void _handle_selection_request_event(XSelectionRequestEvent *p_event) const;
+ void _update_window_mouse_passthrough(WindowID p_window);
String _clipboard_get_impl(Atom p_source, Window x11_window, Atom target) const;
String _clipboard_get(Atom p_source, Window x11_window) const;
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index 7f57644a4c..4873db4b64 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -114,6 +114,7 @@ public:
bool resize_disabled = false;
bool no_focus = false;
bool is_popup = false;
+ bool mpass = false;
Rect2i parent_safe_rect;
};
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 865b8d9711..63280c7887 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -2974,6 +2974,9 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win
case WINDOW_FLAG_NO_FOCUS: {
wd.no_focus = p_enabled;
} break;
+ case WINDOW_FLAG_MOUSE_PASSTHROUGH: {
+ wd.mpass = p_enabled;
+ } break;
case WINDOW_FLAG_POPUP: {
ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window can't be popup.");
ERR_FAIL_COND_MSG([wd.window_object isVisible] && (wd.is_popup != p_enabled), "Popup flag can't changed while window is opened.");
@@ -3013,6 +3016,9 @@ bool DisplayServerMacOS::window_get_flag(WindowFlags p_flag, WindowID p_window)
case WINDOW_FLAG_NO_FOCUS: {
return wd.no_focus;
} break;
+ case WINDOW_FLAG_MOUSE_PASSTHROUGH: {
+ return wd.mpass;
+ } break;
case WINDOW_FLAG_POPUP: {
return wd.is_popup;
} break;
@@ -3487,7 +3493,11 @@ void DisplayServerMacOS::process_events() {
for (KeyValue<WindowID, WindowData> &E : windows) {
WindowData &wd = E.value;
- if (wd.mpath.size() > 0) {
+ if (wd.mpass) {
+ if (![wd.window_object ignoresMouseEvents]) {
+ [wd.window_object setIgnoresMouseEvents:YES];
+ }
+ } else if (wd.mpath.size() > 0) {
update_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream]);
if (Geometry2D::is_point_in_polygon(wd.mouse_pos, wd.mpath)) {
if ([wd.window_object ignoresMouseEvents]) {
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 969bcc3841..914cd07b50 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -735,6 +735,9 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
if (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) {
wd.no_focus = true;
}
+ if (p_flags & WINDOW_FLAG_MOUSE_PASSTHROUGH_BIT) {
+ wd.mpass = true;
+ }
if (p_flags & WINDOW_FLAG_POPUP_BIT) {
wd.is_popup = true;
}
@@ -918,7 +921,7 @@ void DisplayServerWindows::window_set_mouse_passthrough(const Vector<Vector2> &p
void DisplayServerWindows::_update_window_mouse_passthrough(WindowID p_window) {
ERR_FAIL_COND(!windows.has(p_window));
- if (windows[p_window].mpath.size() == 0) {
+ if (windows[p_window].mpass || windows[p_window].mpath.size() == 0) {
SetWindowRgn(windows[p_window].hWnd, nullptr, TRUE);
} else {
POINT *points = (POINT *)memalloc(sizeof(POINT) * windows[p_window].mpath.size());
@@ -1499,6 +1502,10 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
wd.no_focus = p_enabled;
_update_window_style(p_window);
} break;
+ case WINDOW_FLAG_MOUSE_PASSTHROUGH: {
+ wd.mpass = p_enabled;
+ _update_window_mouse_passthrough(p_window);
+ } break;
case WINDOW_FLAG_POPUP: {
ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window can't be popup.");
ERR_FAIL_COND_MSG(IsWindowVisible(wd.hWnd) && (wd.is_popup != p_enabled), "Popup flag can't changed while window is opened.");
@@ -1530,6 +1537,9 @@ bool DisplayServerWindows::window_get_flag(WindowFlags p_flag, WindowID p_window
case WINDOW_FLAG_NO_FOCUS: {
return wd.no_focus;
} break;
+ case WINDOW_FLAG_MOUSE_PASSTHROUGH: {
+ return wd.mpass;
+ } break;
case WINDOW_FLAG_POPUP: {
return wd.is_popup;
} break;
@@ -2464,6 +2474,11 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
// Process window messages.
switch (uMsg) {
+ case WM_NCHITTEST: {
+ if (windows[window_id].mpass) {
+ return HTTRANSPARENT;
+ }
+ } break;
case WM_MOUSEACTIVATE: {
if (windows[window_id].no_focus) {
return MA_NOACTIVATEANDEAT; // Do not activate, and discard mouse messages.
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 84f2dee35e..ce4b94af59 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -370,6 +370,7 @@ class DisplayServerWindows : public DisplayServer {
bool window_has_focus = false;
bool exclusive = false;
bool context_created = false;
+ bool mpass = false;
// Used to transfer data between events using timer.
WPARAM saved_wparam;