|
@@ -546,6 +546,9 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
|
|
if (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) {
|
|
if (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) {
|
|
wd.no_focus = true;
|
|
wd.no_focus = true;
|
|
}
|
|
}
|
|
|
|
+ if (p_flags & WINDOW_FLAG_POPUP_BIT) {
|
|
|
|
+ wd.is_popup = true;
|
|
|
|
+ }
|
|
|
|
|
|
// Inherit icons from MAIN_WINDOW for all sub windows.
|
|
// Inherit icons from MAIN_WINDOW for all sub windows.
|
|
HICON mainwindow_icon = (HICON)SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_GETICON, ICON_SMALL, 0);
|
|
HICON mainwindow_icon = (HICON)SendMessage(windows[MAIN_WINDOW_ID].hWnd, WM_GETICON, ICON_SMALL, 0);
|
|
@@ -563,13 +566,14 @@ void DisplayServerWindows::show_window(WindowID p_id) {
|
|
ERR_FAIL_COND(!windows.has(p_id));
|
|
ERR_FAIL_COND(!windows.has(p_id));
|
|
|
|
|
|
WindowData &wd = windows[p_id];
|
|
WindowData &wd = windows[p_id];
|
|
|
|
+ popup_open(p_id);
|
|
|
|
|
|
if (p_id != MAIN_WINDOW_ID) {
|
|
if (p_id != MAIN_WINDOW_ID) {
|
|
_update_window_style(p_id);
|
|
_update_window_style(p_id);
|
|
}
|
|
}
|
|
|
|
|
|
- ShowWindow(wd.hWnd, wd.no_focus ? SW_SHOWNOACTIVATE : SW_SHOW); // Show the window.
|
|
|
|
- if (!wd.no_focus) {
|
|
|
|
|
|
+ ShowWindow(wd.hWnd, (wd.no_focus || wd.is_popup) ? SW_SHOWNOACTIVATE : SW_SHOW); // Show the window.
|
|
|
|
+ if (!wd.no_focus && !wd.is_popup) {
|
|
SetForegroundWindow(wd.hWnd); // Slightly higher priority.
|
|
SetForegroundWindow(wd.hWnd); // Slightly higher priority.
|
|
SetFocus(wd.hWnd); // Set keyboard focus.
|
|
SetFocus(wd.hWnd); // Set keyboard focus.
|
|
}
|
|
}
|
|
@@ -581,6 +585,8 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
|
|
ERR_FAIL_COND(!windows.has(p_window));
|
|
ERR_FAIL_COND(!windows.has(p_window));
|
|
ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window cannot be deleted.");
|
|
ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window cannot be deleted.");
|
|
|
|
|
|
|
|
+ popup_close(p_window);
|
|
|
|
+
|
|
WindowData &wd = windows[p_window];
|
|
WindowData &wd = windows[p_window];
|
|
|
|
|
|
while (wd.transient_children.size()) {
|
|
while (wd.transient_children.size()) {
|
|
@@ -1019,6 +1025,7 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre
|
|
r_style_ex = WS_EX_WINDOWEDGE;
|
|
r_style_ex = WS_EX_WINDOWEDGE;
|
|
if (p_main_window) {
|
|
if (p_main_window) {
|
|
r_style_ex |= WS_EX_APPWINDOW;
|
|
r_style_ex |= WS_EX_APPWINDOW;
|
|
|
|
+ r_style |= WS_VISIBLE;
|
|
}
|
|
}
|
|
|
|
|
|
if (p_fullscreen || p_borderless) {
|
|
if (p_fullscreen || p_borderless) {
|
|
@@ -1037,11 +1044,15 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre
|
|
r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
|
|
r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- r_style |= WS_VISIBLE;
|
|
|
|
|
|
|
|
if (p_no_activate_focus) {
|
|
if (p_no_activate_focus) {
|
|
r_style_ex |= WS_EX_TOPMOST | WS_EX_NOACTIVATE;
|
|
r_style_ex |= WS_EX_TOPMOST | WS_EX_NOACTIVATE;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (!p_borderless && !p_no_activate_focus) {
|
|
|
|
+ r_style |= WS_VISIBLE;
|
|
|
|
+ }
|
|
|
|
+
|
|
r_style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
|
r_style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
|
r_style_ex |= WS_EX_ACCEPTFILES;
|
|
r_style_ex |= WS_EX_ACCEPTFILES;
|
|
}
|
|
}
|
|
@@ -1055,12 +1066,12 @@ void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repain
|
|
DWORD style = 0;
|
|
DWORD style = 0;
|
|
DWORD style_ex = 0;
|
|
DWORD style_ex = 0;
|
|
|
|
|
|
- _get_window_style(p_window == MAIN_WINDOW_ID, wd.fullscreen, wd.multiwindow_fs, wd.borderless, wd.resizable, wd.maximized, wd.no_focus, style, style_ex);
|
|
|
|
|
|
+ _get_window_style(p_window == MAIN_WINDOW_ID, wd.fullscreen, wd.multiwindow_fs, wd.borderless, wd.resizable, wd.maximized, wd.no_focus || wd.is_popup, style, style_ex);
|
|
|
|
|
|
SetWindowLongPtr(wd.hWnd, GWL_STYLE, style);
|
|
SetWindowLongPtr(wd.hWnd, GWL_STYLE, style);
|
|
SetWindowLongPtr(wd.hWnd, GWL_EXSTYLE, style_ex);
|
|
SetWindowLongPtr(wd.hWnd, GWL_EXSTYLE, style_ex);
|
|
|
|
|
|
- SetWindowPos(wd.hWnd, wd.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | (wd.no_focus ? SWP_NOACTIVATE : 0));
|
|
|
|
|
|
+ SetWindowPos(wd.hWnd, wd.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | ((wd.no_focus || wd.is_popup) ? SWP_NOACTIVATE : 0));
|
|
|
|
|
|
if (p_repaint) {
|
|
if (p_repaint) {
|
|
RECT rect;
|
|
RECT rect;
|
|
@@ -1211,6 +1222,7 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
|
|
wd.borderless = p_enabled;
|
|
wd.borderless = p_enabled;
|
|
_update_window_style(p_window);
|
|
_update_window_style(p_window);
|
|
_update_window_mouse_passthrough(p_window);
|
|
_update_window_mouse_passthrough(p_window);
|
|
|
|
+ ShowWindow(wd.hWnd, (wd.no_focus || wd.is_popup) ? SW_SHOWNOACTIVATE : SW_SHOW); // Show the window.
|
|
} break;
|
|
} break;
|
|
case WINDOW_FLAG_ALWAYS_ON_TOP: {
|
|
case WINDOW_FLAG_ALWAYS_ON_TOP: {
|
|
ERR_FAIL_COND_MSG(wd.transient_parent != INVALID_WINDOW_ID && p_enabled, "Transient windows can't become on top");
|
|
ERR_FAIL_COND_MSG(wd.transient_parent != INVALID_WINDOW_ID && p_enabled, "Transient windows can't become on top");
|
|
@@ -1224,6 +1236,11 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
|
|
wd.no_focus = p_enabled;
|
|
wd.no_focus = p_enabled;
|
|
_update_window_style(p_window);
|
|
_update_window_style(p_window);
|
|
} break;
|
|
} 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), "Pupup flag can't changed while window is opened.");
|
|
|
|
+ wd.is_popup = p_enabled;
|
|
|
|
+ } break;
|
|
case WINDOW_FLAG_MAX:
|
|
case WINDOW_FLAG_MAX:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -1250,6 +1267,9 @@ bool DisplayServerWindows::window_get_flag(WindowFlags p_flag, WindowID p_window
|
|
case WINDOW_FLAG_NO_FOCUS: {
|
|
case WINDOW_FLAG_NO_FOCUS: {
|
|
return wd.no_focus;
|
|
return wd.no_focus;
|
|
} break;
|
|
} break;
|
|
|
|
+ case WINDOW_FLAG_POPUP: {
|
|
|
|
+ return wd.is_popup;
|
|
|
|
+ } break;
|
|
case WINDOW_FLAG_MAX:
|
|
case WINDOW_FLAG_MAX:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -1278,7 +1298,9 @@ void DisplayServerWindows::window_move_to_foreground(WindowID p_window) {
|
|
ERR_FAIL_COND(!windows.has(p_window));
|
|
ERR_FAIL_COND(!windows.has(p_window));
|
|
WindowData &wd = windows[p_window];
|
|
WindowData &wd = windows[p_window];
|
|
|
|
|
|
- SetForegroundWindow(wd.hWnd);
|
|
|
|
|
|
+ if (!wd.no_focus && !wd.is_popup) {
|
|
|
|
+ SetForegroundWindow(wd.hWnd);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
bool DisplayServerWindows::window_can_draw(WindowID p_window) const {
|
|
bool DisplayServerWindows::window_can_draw(WindowID p_window) const {
|
|
@@ -1989,33 +2011,145 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event)
|
|
Variant ret;
|
|
Variant ret;
|
|
Callable::CallError ce;
|
|
Callable::CallError ce;
|
|
|
|
|
|
|
|
+ {
|
|
|
|
+ List<WindowID>::Element *E = popup_list.front();
|
|
|
|
+ if (E && Object::cast_to<InputEventKey>(*p_event)) {
|
|
|
|
+ // Redirect keyboard input to active popup.
|
|
|
|
+ if (windows.has(E->get())) {
|
|
|
|
+ Callable callable = windows[E->get()].input_event_callback;
|
|
|
|
+ if (callable.is_valid()) {
|
|
|
|
+ callable.call((const Variant **)&evp, 1, ret, ce);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ in_dispatch_input_event = false;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
Ref<InputEventFromWindow> event_from_window = p_event;
|
|
Ref<InputEventFromWindow> event_from_window = p_event;
|
|
if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) {
|
|
if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) {
|
|
// Send to a single window.
|
|
// Send to a single window.
|
|
- if (!windows.has(event_from_window->get_window_id())) {
|
|
|
|
- in_dispatch_input_event = false;
|
|
|
|
- ERR_FAIL_MSG("DisplayServerWindows: Invalid window id in input event.");
|
|
|
|
- }
|
|
|
|
- Callable callable = windows[event_from_window->get_window_id()].input_event_callback;
|
|
|
|
- if (callable.is_null()) {
|
|
|
|
- in_dispatch_input_event = false;
|
|
|
|
- return;
|
|
|
|
|
|
+ if (windows.has(event_from_window->get_window_id())) {
|
|
|
|
+ Callable callable = windows[event_from_window->get_window_id()].input_event_callback;
|
|
|
|
+ if (callable.is_valid()) {
|
|
|
|
+ callable.call((const Variant **)&evp, 1, ret, ce);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- callable.call((const Variant **)&evp, 1, ret, ce);
|
|
|
|
} else {
|
|
} else {
|
|
// Send to all windows.
|
|
// Send to all windows.
|
|
for (const KeyValue<WindowID, WindowData> &E : windows) {
|
|
for (const KeyValue<WindowID, WindowData> &E : windows) {
|
|
const Callable callable = E.value.input_event_callback;
|
|
const Callable callable = E.value.input_event_callback;
|
|
- if (callable.is_null()) {
|
|
|
|
- continue;
|
|
|
|
|
|
+ if (callable.is_valid()) {
|
|
|
|
+ callable.call((const Variant **)&evp, 1, ret, ce);
|
|
}
|
|
}
|
|
- callable.call((const Variant **)&evp, 1, ret, ce);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
in_dispatch_input_event = false;
|
|
in_dispatch_input_event = false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam) {
|
|
|
|
+ DisplayServerWindows *ds_win = static_cast<DisplayServerWindows *>(DisplayServer::get_singleton());
|
|
|
|
+ if (ds_win) {
|
|
|
|
+ return ds_win->MouseProc(code, wParam, lParam);
|
|
|
|
+ } else {
|
|
|
|
+ return ::CallNextHookEx(nullptr, code, wParam, lParam);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+DisplayServer::WindowID DisplayServerWindows::window_get_active_popup() const {
|
|
|
|
+ const List<WindowID>::Element *E = popup_list.back();
|
|
|
|
+ if (E) {
|
|
|
|
+ return E->get();
|
|
|
|
+ } else {
|
|
|
|
+ return INVALID_WINDOW_ID;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void DisplayServerWindows::window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) {
|
|
|
|
+ _THREAD_SAFE_METHOD_
|
|
|
|
+
|
|
|
|
+ ERR_FAIL_COND(!windows.has(p_window));
|
|
|
|
+ WindowData &wd = windows[p_window];
|
|
|
|
+ wd.parent_safe_rect = p_rect;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Rect2i DisplayServerWindows::window_get_popup_safe_rect(WindowID p_window) const {
|
|
|
|
+ _THREAD_SAFE_METHOD_
|
|
|
|
+
|
|
|
|
+ ERR_FAIL_COND_V(!windows.has(p_window), Rect2i());
|
|
|
|
+ const WindowData &wd = windows[p_window];
|
|
|
|
+ return wd.parent_safe_rect;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void DisplayServerWindows::popup_open(WindowID p_window) {
|
|
|
|
+ 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.
|
|
|
|
+ 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()], DisplayServerWindows::WINDOW_EVENT_CLOSE_REQUEST);
|
|
|
|
+ List<WindowID>::Element *F = E->prev();
|
|
|
|
+ popup_list.erase(E);
|
|
|
|
+ E = F;
|
|
|
|
+ } else {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ time_since_popup = OS::get_singleton()->get_ticks_msec();
|
|
|
|
+ popup_list.push_back(p_window);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void DisplayServerWindows::popup_close(WindowID p_window) {
|
|
|
|
+ List<WindowID>::Element *E = popup_list.find(p_window);
|
|
|
|
+ while (E) {
|
|
|
|
+ _send_window_event(windows[E->get()], DisplayServerWindows::WINDOW_EVENT_CLOSE_REQUEST);
|
|
|
|
+ List<WindowID>::Element *F = E->next();
|
|
|
|
+ popup_list.erase(E);
|
|
|
|
+ E = F;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+LRESULT DisplayServerWindows::MouseProc(int code, WPARAM wParam, LPARAM lParam) {
|
|
|
|
+ _THREAD_SAFE_METHOD_
|
|
|
|
+ uint64_t delta = OS::get_singleton()->get_ticks_msec() - time_since_popup;
|
|
|
|
+ if (delta > 250) {
|
|
|
|
+ switch (wParam) {
|
|
|
|
+ case WM_NCLBUTTONDOWN:
|
|
|
|
+ case WM_NCRBUTTONDOWN:
|
|
|
|
+ case WM_NCMBUTTONDOWN:
|
|
|
|
+ case WM_LBUTTONDOWN:
|
|
|
|
+ case WM_RBUTTONDOWN:
|
|
|
|
+ case WM_MBUTTONDOWN: {
|
|
|
|
+ MOUSEHOOKSTRUCT *ms = (MOUSEHOOKSTRUCT *)lParam;
|
|
|
|
+ Point2i pos = Point2i(ms->pt.x, ms->pt.y);
|
|
|
|
+ List<WindowID>::Element *E = popup_list.back();
|
|
|
|
+ while (E) {
|
|
|
|
+ // Popup window area.
|
|
|
|
+ Rect2i win_rect = Rect2i(window_get_position(E->get()), window_get_size(E->get()));
|
|
|
|
+ // Area of the parent window, which responsible for opening sub-menu.
|
|
|
|
+ Rect2i safe_rect = window_get_popup_safe_rect(E->get());
|
|
|
|
+ if (win_rect.has_point(pos)) {
|
|
|
|
+ break;
|
|
|
|
+ } else if (safe_rect != Rect2i() && safe_rect.has_point(pos)) {
|
|
|
|
+ break;
|
|
|
|
+ } else {
|
|
|
|
+ _send_window_event(windows[E->get()], DisplayServerWindows::WINDOW_EVENT_CLOSE_REQUEST);
|
|
|
|
+ List<WindowID>::Element *F = E->prev();
|
|
|
|
+ popup_list.erase(E);
|
|
|
|
+ E = F;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return ::CallNextHookEx(mouse_monitor, code, wParam, lParam);
|
|
|
|
+}
|
|
|
|
+
|
|
// Our default window procedure to handle processing of window-related system messages/events.
|
|
// Our default window procedure to handle processing of window-related system messages/events.
|
|
// Also known as DefProc or DefWindowProc.
|
|
// Also known as DefProc or DefWindowProc.
|
|
// See: https://docs.microsoft.com/en-us/windows/win32/winmsg/window-procedures
|
|
// See: https://docs.microsoft.com/en-us/windows/win32/winmsg/window-procedures
|
|
@@ -2048,6 +2182,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
|
|
|
|
|
// Process window messages.
|
|
// Process window messages.
|
|
switch (uMsg) {
|
|
switch (uMsg) {
|
|
|
|
+ case WM_MOUSEACTIVATE: {
|
|
|
|
+ if (windows[window_id].no_focus) {
|
|
|
|
+ return MA_NOACTIVATEANDEAT; // Do not activate, and discard mouse messages.
|
|
|
|
+ } else if (windows[window_id].is_popup) {
|
|
|
|
+ return MA_NOACTIVATE; // Do not activate, but process mouse messages.
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
case WM_SETFOCUS: {
|
|
case WM_SETFOCUS: {
|
|
windows[window_id].window_has_focus = true;
|
|
windows[window_id].window_has_focus = true;
|
|
last_focused_window = window_id;
|
|
last_focused_window = window_id;
|
|
@@ -2309,7 +2450,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
|
mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
|
|
mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
|
|
old_x = mm->get_position().x;
|
|
old_x = mm->get_position().x;
|
|
old_y = mm->get_position().y;
|
|
old_y = mm->get_position().y;
|
|
- if (windows[window_id].window_has_focus) {
|
|
|
|
|
|
+ if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
|
|
Input::get_singleton()->parse_input_event(mm);
|
|
Input::get_singleton()->parse_input_event(mm);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2451,7 +2592,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
|
mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
|
|
mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
|
|
old_x = mm->get_position().x;
|
|
old_x = mm->get_position().x;
|
|
old_y = mm->get_position().y;
|
|
old_y = mm->get_position().y;
|
|
- if (windows[window_id].window_has_focus) {
|
|
|
|
|
|
+ if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
|
|
Input::get_singleton()->parse_input_event(mm);
|
|
Input::get_singleton()->parse_input_event(mm);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2551,7 +2692,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
|
mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
|
|
mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
|
|
old_x = mm->get_position().x;
|
|
old_x = mm->get_position().x;
|
|
old_y = mm->get_position().y;
|
|
old_y = mm->get_position().y;
|
|
- if (windows[window_id].window_has_focus) {
|
|
|
|
|
|
+ if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
|
|
Input::get_singleton()->parse_input_event(mm);
|
|
Input::get_singleton()->parse_input_event(mm);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3462,6 +3603,8 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+ HHOOK mouse_monitor = SetWindowsHookEx(WH_MOUSE, ::MouseProc, nullptr, GetCurrentThreadId());
|
|
|
|
+
|
|
Point2i window_position(
|
|
Point2i window_position(
|
|
(screen_get_size(0).width - p_resolution.width) / 2,
|
|
(screen_get_size(0).width - p_resolution.width) / 2,
|
|
(screen_get_size(0).height - p_resolution.height) / 2);
|
|
(screen_get_size(0).height - p_resolution.height) / 2);
|
|
@@ -3545,6 +3688,10 @@ DisplayServerWindows::~DisplayServerWindows() {
|
|
|
|
|
|
cursors_cache.clear();
|
|
cursors_cache.clear();
|
|
|
|
|
|
|
|
+ if (mouse_monitor) {
|
|
|
|
+ UnhookWindowsHookEx(mouse_monitor);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (user_proc) {
|
|
if (user_proc) {
|
|
SetWindowLongPtr(windows[MAIN_WINDOW_ID].hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc);
|
|
SetWindowLongPtr(windows[MAIN_WINDOW_ID].hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc);
|
|
}
|
|
}
|