Skip to content

Commit 65cf7c1

Browse files
committed
Merge pull request #101221 from bruvzg/win_dec_exp
[Window] Expose `start_drag` and `start_resize` methods (for both native and embedded windows).
2 parents 2db8f88 + 8d911b2 commit 65cf7c1

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
@@ -3991,6 +3991,10 @@ void DisplayServerWindows::window_start_drag(WindowID p_window) {
39913991
ERR_FAIL_COND(!windows.has(p_window));
39923992
WindowData &wd = windows[p_window];
39933993

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

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

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

40124020
POINT coords;

scene/main/viewport.cpp

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

2950+
void Viewport::_window_start_drag(Window *p_window) {
2951+
int index = _sub_window_find(p_window);
2952+
ERR_FAIL_COND(index == -1);
2953+
2954+
SubWindow sw = gui.sub_windows.write[index];
2955+
2956+
if (gui.subwindow_focused != sw.window) {
2957+
// Refocus.
2958+
_sub_window_grab_focus(sw.window);
2959+
}
2960+
2961+
gui.subwindow_drag = SUB_WINDOW_DRAG_MOVE;
2962+
gui.subwindow_drag_from = get_mouse_position();
2963+
gui.subwindow_drag_pos = sw.window->get_position();
2964+
gui.currently_dragged_subwindow = sw.window;
2965+
2966+
_sub_window_update(sw.window);
2967+
}
2968+
2969+
void Viewport::_window_start_resize(SubWindowResize p_edge, Window *p_window) {
2970+
int index = _sub_window_find(p_window);
2971+
ERR_FAIL_COND(index == -1);
2972+
2973+
SubWindow sw = gui.sub_windows.write[index];
2974+
Rect2i r = Rect2i(sw.window->get_position(), sw.window->get_size());
2975+
2976+
if (gui.subwindow_focused != sw.window) {
2977+
// Refocus.
2978+
_sub_window_grab_focus(sw.window);
2979+
}
2980+
2981+
gui.subwindow_drag = SUB_WINDOW_DRAG_RESIZE;
2982+
gui.subwindow_resize_mode = p_edge;
2983+
gui.subwindow_resize_from_rect = r;
2984+
gui.subwindow_drag_from = get_mouse_position();
2985+
gui.subwindow_drag_pos = sw.window->get_position();
2986+
gui.currently_dragged_subwindow = sw.window;
2987+
2988+
_sub_window_update(sw.window);
2989+
}
2990+
29502991
void Viewport::_update_mouse_over() {
29512992
// Update gui.mouse_over and gui.subwindow_over in all Viewports.
29522993
// 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)