Skip to content

Commit 8d911b2

Browse files
committed
[Window] Expose start_drag and start_resize methods (for both native and embedded windows).
1 parent aa65940 commit 8d911b2

File tree

7 files changed

+127
-0
lines changed

7 files changed

+127
-0
lines changed

doc/classes/Window.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,19 @@
557557
Makes the [Window] appear. This enables interactions with the [Window] and doesn't change any of its property other than visibility (unlike e.g. [method popup]).
558558
</description>
559559
</method>
560+
<method name="start_drag">
561+
<return type="void" />
562+
<description>
563+
Starts an interactive drag operation on the window, using the current mouse position. Call this method when handling a mouse button being pressed to simulate a pressed event on the window's title bar. Using this method allows the window to participate in space switching, tiling, and other system features.
564+
</description>
565+
</method>
566+
<method name="start_resize">
567+
<return type="void" />
568+
<param index="0" name="edge" type="int" enum="DisplayServer.WindowResizeEdge" />
569+
<description>
570+
Starts an interactive resize operation on the window, using the current mouse position. Call this method when handling a mouse button being pressed to simulate a pressed event on the window's edge.
571+
</description>
572+
</method>
560573
</methods>
561574
<members>
562575
<member name="always_on_top" type="bool" setter="set_flag" getter="get_flag" default="false">

platform/linuxbsd/x11/display_server_x11.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5496,6 +5496,10 @@ void DisplayServerX11::window_start_drag(WindowID p_window) {
54965496
ERR_FAIL_COND(!windows.has(p_window));
54975497
WindowData &wd = windows[p_window];
54985498

5499+
if (wd.embed_parent) {
5500+
return; // Embedded window.
5501+
}
5502+
54995503
XClientMessageEvent m;
55005504
memset(&m, 0, sizeof(m));
55015505

@@ -5532,6 +5536,10 @@ void DisplayServerX11::window_start_resize(WindowResizeEdge p_edge, WindowID p_w
55325536
ERR_FAIL_COND(!windows.has(p_window));
55335537
WindowData &wd = windows[p_window];
55345538

5539+
if (wd.embed_parent) {
5540+
return; // Embedded window.
5541+
}
5542+
55355543
XClientMessageEvent m;
55365544
memset(&m, 0, sizeof(m));
55375545

platform/windows/display_server_windows.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3990,6 +3990,10 @@ void DisplayServerWindows::window_start_drag(WindowID p_window) {
39903990
ERR_FAIL_COND(!windows.has(p_window));
39913991
WindowData &wd = windows[p_window];
39923992

3993+
if (wd.parent_hwnd) {
3994+
return; // Embedded window.
3995+
}
3996+
39933997
ReleaseCapture();
39943998

39953999
POINT coords;
@@ -4006,6 +4010,10 @@ void DisplayServerWindows::window_start_resize(WindowResizeEdge p_edge, WindowID
40064010
ERR_FAIL_COND(!windows.has(p_window));
40074011
WindowData &wd = windows[p_window];
40084012

4013+
if (wd.parent_hwnd) {
4014+
return; // Embedded window.
4015+
}
4016+
40094017
ReleaseCapture();
40104018

40114019
POINT coords;

scene/main/viewport.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2956,6 +2956,47 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
29562956
return true;
29572957
}
29582958

2959+
void Viewport::_window_start_drag(Window *p_window) {
2960+
int index = _sub_window_find(p_window);
2961+
ERR_FAIL_COND(index == -1);
2962+
2963+
SubWindow sw = gui.sub_windows.write[index];
2964+
2965+
if (gui.subwindow_focused != sw.window) {
2966+
// Refocus.
2967+
_sub_window_grab_focus(sw.window);
2968+
}
2969+
2970+
gui.subwindow_drag = SUB_WINDOW_DRAG_MOVE;
2971+
gui.subwindow_drag_from = get_mouse_position();
2972+
gui.subwindow_drag_pos = sw.window->get_position();
2973+
gui.currently_dragged_subwindow = sw.window;
2974+
2975+
_sub_window_update(sw.window);
2976+
}
2977+
2978+
void Viewport::_window_start_resize(SubWindowResize p_edge, Window *p_window) {
2979+
int index = _sub_window_find(p_window);
2980+
ERR_FAIL_COND(index == -1);
2981+
2982+
SubWindow sw = gui.sub_windows.write[index];
2983+
Rect2i r = Rect2i(sw.window->get_position(), sw.window->get_size());
2984+
2985+
if (gui.subwindow_focused != sw.window) {
2986+
// Refocus.
2987+
_sub_window_grab_focus(sw.window);
2988+
}
2989+
2990+
gui.subwindow_drag = SUB_WINDOW_DRAG_RESIZE;
2991+
gui.subwindow_resize_mode = p_edge;
2992+
gui.subwindow_resize_from_rect = r;
2993+
gui.subwindow_drag_from = get_mouse_position();
2994+
gui.subwindow_drag_pos = sw.window->get_position();
2995+
gui.currently_dragged_subwindow = sw.window;
2996+
2997+
_sub_window_update(sw.window);
2998+
}
2999+
29593000
void Viewport::_update_mouse_over() {
29603001
// Update gui.mouse_over and gui.subwindow_over in all Viewports.
29613002
// Send necessary mouse_enter/mouse_exit signals and the MOUSE_ENTER/MOUSE_EXIT notifications for every Viewport in the SceneTree.

scene/main/viewport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,9 @@ class Viewport : public Node {
488488
void _process_dirty_canvas_parent_orders();
489489
void _propagate_world_2d_changed(Node *p_node);
490490

491+
void _window_start_drag(Window *p_window);
492+
void _window_start_resize(SubWindowResize p_edge, Window *p_window);
493+
491494
protected:
492495
bool _set_size(const Size2i &p_size, const Size2i &p_size_2d_override, bool p_allocated);
493496

scene/main/window.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,6 +1998,54 @@ bool Window::has_focus() const {
19981998
return focused;
19991999
}
20002000

2001+
void Window::start_drag() {
2002+
ERR_MAIN_THREAD_GUARD;
2003+
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
2004+
DisplayServer::get_singleton()->window_start_drag(window_id);
2005+
} else if (embedder) {
2006+
embedder->_window_start_drag(this);
2007+
}
2008+
}
2009+
2010+
void Window::start_resize(DisplayServer::WindowResizeEdge p_edge) {
2011+
ERR_MAIN_THREAD_GUARD;
2012+
if (get_flag(FLAG_RESIZE_DISABLED)) {
2013+
return;
2014+
}
2015+
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
2016+
DisplayServer::get_singleton()->window_start_resize(p_edge, window_id);
2017+
} else if (embedder) {
2018+
switch (p_edge) {
2019+
case DisplayServer::WINDOW_EDGE_TOP_LEFT: {
2020+
embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_TOP_LEFT, this);
2021+
} break;
2022+
case DisplayServer::WINDOW_EDGE_TOP: {
2023+
embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_TOP, this);
2024+
} break;
2025+
case DisplayServer::WINDOW_EDGE_TOP_RIGHT: {
2026+
embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_TOP_RIGHT, this);
2027+
} break;
2028+
case DisplayServer::WINDOW_EDGE_LEFT: {
2029+
embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_LEFT, this);
2030+
} break;
2031+
case DisplayServer::WINDOW_EDGE_RIGHT: {
2032+
embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_RIGHT, this);
2033+
} break;
2034+
case DisplayServer::WINDOW_EDGE_BOTTOM_LEFT: {
2035+
embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_BOTTOM_LEFT, this);
2036+
} break;
2037+
case DisplayServer::WINDOW_EDGE_BOTTOM: {
2038+
embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_BOTTOM, this);
2039+
} break;
2040+
case DisplayServer::WINDOW_EDGE_BOTTOM_RIGHT: {
2041+
embedder->_window_start_resize(Viewport::SUB_WINDOW_RESIZE_BOTTOM_RIGHT, this);
2042+
} break;
2043+
default:
2044+
break;
2045+
}
2046+
}
2047+
}
2048+
20012049
Rect2i Window::get_usable_parent_rect() const {
20022050
ERR_READ_THREAD_GUARD_V(Rect2i());
20032051
ERR_FAIL_COND_V(!is_inside_tree(), Rect2());
@@ -2888,6 +2936,9 @@ void Window::_bind_methods() {
28882936
ClassDB::bind_method(D_METHOD("has_focus"), &Window::has_focus);
28892937
ClassDB::bind_method(D_METHOD("grab_focus"), &Window::grab_focus);
28902938

2939+
ClassDB::bind_method(D_METHOD("start_drag"), &Window::start_drag);
2940+
ClassDB::bind_method(D_METHOD("start_resize", "edge"), &Window::start_resize);
2941+
28912942
ClassDB::bind_method(D_METHOD("set_ime_active", "active"), &Window::set_ime_active);
28922943
ClassDB::bind_method(D_METHOD("set_ime_position", "position"), &Window::set_ime_position);
28932944

scene/main/window.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,9 @@ class Window : public Viewport {
401401
void grab_focus();
402402
bool has_focus() const;
403403

404+
void start_drag();
405+
void start_resize(DisplayServer::WindowResizeEdge p_edge);
406+
404407
Rect2i get_usable_parent_rect() const;
405408

406409
// Internationalization.

0 commit comments

Comments
 (0)