diff options
Diffstat (limited to 'platform/windows/display_server_windows.cpp')
-rw-r--r-- | platform/windows/display_server_windows.cpp | 137 |
1 files changed, 113 insertions, 24 deletions
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index bc767a47e5..e7864ebac0 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -741,9 +741,20 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type, case WINDOW_HANDLE: { return (int64_t)windows[p_window].hWnd; } +#if defined(GLES3_ENABLED) case WINDOW_VIEW: { - return 0; // Not supported. + if (gl_manager) { + return (int64_t)gl_manager->get_hdc(p_window); + } + return 0; + } + case OPENGL_CONTEXT: { + if (gl_manager) { + return (int64_t)gl_manager->get_hglrc(p_window); + } + return 0; } +#endif default: { return 0; } @@ -898,6 +909,24 @@ Point2i DisplayServerWindows::window_get_position(WindowID p_window) const { return Point2i(point.x, point.y); } +Point2i DisplayServerWindows::window_get_position_with_decorations(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), Point2i()); + const WindowData &wd = windows[p_window]; + + if (wd.minimized) { + return wd.last_pos; + } + + RECT r; + if (GetWindowRect(wd.hWnd, &r)) { + return Point2i(r.left, r.top); + } + + return Point2i(); +} + void DisplayServerWindows::_update_real_mouse_position(WindowID p_window) { ERR_FAIL_COND(!windows.has(p_window)); @@ -1113,7 +1142,7 @@ Size2i DisplayServerWindows::window_get_size(WindowID p_window) const { return Size2(); } -Size2i DisplayServerWindows::window_get_real_size(WindowID p_window) const { +Size2i DisplayServerWindows::window_get_size_with_decorations(WindowID p_window) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!windows.has(p_window), Size2i()); @@ -1881,7 +1910,7 @@ void DisplayServerWindows::set_native_icon(const String &p_filename) { pos += sizeof(WORD); f->seek(pos); - icon_dir = (ICONDIR *)memrealloc(icon_dir, 3 * sizeof(WORD) + icon_dir->idCount * sizeof(ICONDIRENTRY)); + icon_dir = (ICONDIR *)memrealloc(icon_dir, sizeof(ICONDIR) - sizeof(ICONDIRENTRY) + icon_dir->idCount * sizeof(ICONDIRENTRY)); f->get_buffer((uint8_t *)&icon_dir->idEntries[0], icon_dir->idCount * sizeof(ICONDIRENTRY)); int small_icon_index = -1; // Select 16x16 with largest color count. @@ -2012,6 +2041,12 @@ void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsyn context_vulkan->set_vsync_mode(p_window, p_vsync_mode); } #endif + +#if defined(GLES3_ENABLED) + if (gl_manager) { + gl_manager->set_use_vsync(p_window, p_vsync_mode != DisplayServer::VSYNC_DISABLED); + } +#endif } DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_window) const { @@ -2021,6 +2056,13 @@ DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_ return context_vulkan->get_vsync_mode(p_window); } #endif + +#if defined(GLES3_ENABLED) + if (gl_manager) { + return gl_manager->is_using_vsync(p_window) ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED; + } +#endif + return DisplayServer::VSYNC_ENABLED; } @@ -2390,7 +2432,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_GETMINMAXINFO: { if (windows[window_id].resizable && !windows[window_id].fullscreen) { // Size of window decorations. - Size2 decor = window_get_real_size(window_id) - window_get_size(window_id); + Size2 decor = window_get_size_with_decorations(window_id) - window_get_size(window_id); MINMAXINFO *min_max_info = (MINMAXINFO *)lParam; if (windows[window_id].min_size != Size2()) { @@ -2444,10 +2486,16 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA return 0; // Jump back. } case WM_MOUSELEAVE: { - old_invalid = true; - windows[window_id].mouse_outside = true; + if (window_mouseover_id == window_id) { + old_invalid = true; + window_mouseover_id = INVALID_WINDOW_ID; - _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT); + _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT); + } else if (window_mouseover_id != INVALID_WINDOW_ID && windows.has(window_mouseover_id)) { + // This is reached during drag and drop, after dropping in a different window. + // Once-off notification, must call again. + track_mouse_leave_event(windows[window_mouseover_id].hWnd); + } } break; case WM_INPUT: { @@ -2678,17 +2726,21 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } - if (windows[window_id].mouse_outside) { + if (window_mouseover_id != window_id) { // Mouse enter. if (mouse_mode != MOUSE_MODE_CAPTURED) { + if (window_mouseover_id != INVALID_WINDOW_ID && windows.has(window_mouseover_id)) { + // Leave previous window. + _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT); + } _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); } CursorShape c = cursor_shape; cursor_shape = CURSOR_MAX; cursor_set_shape(c); - windows[window_id].mouse_outside = false; + window_mouseover_id = window_id; // Once-off notification, must call again. track_mouse_leave_event(hWnd); @@ -2779,17 +2831,29 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA } } - if (windows[window_id].mouse_outside) { + DisplayServer::WindowID over_id = get_window_at_screen_position(mouse_get_position()); + if (windows.has(over_id) && !Rect2(window_get_position(over_id), Point2(windows[over_id].width, windows[over_id].height)).has_point(mouse_get_position())) { + // Don't consider the windowborder as part of the window. + over_id = INVALID_WINDOW_ID; + } + if (window_mouseover_id != over_id) { // Mouse enter. if (mouse_mode != MOUSE_MODE_CAPTURED) { - _send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER); + if (window_mouseover_id != INVALID_WINDOW_ID && windows.has(window_mouseover_id)) { + // Leave previous window. + _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT); + } + + if (over_id != INVALID_WINDOW_ID && windows.has(over_id)) { + _send_window_event(windows[over_id], WINDOW_EVENT_MOUSE_ENTER); + } } CursorShape c = cursor_shape; cursor_shape = CURSOR_MAX; cursor_set_shape(c); - windows[window_id].mouse_outside = false; + window_mouseover_id = over_id; // Once-off notification, must call again. track_mouse_leave_event(hWnd); @@ -2800,9 +2864,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA break; } + DisplayServer::WindowID receiving_window_id = _get_focused_window_or_popup(); + if (receiving_window_id == INVALID_WINDOW_ID) { + receiving_window_id = window_id; + } Ref<InputEventMouseMotion> mm; mm.instantiate(); - mm->set_window_id(window_id); + mm->set_window_id(receiving_window_id); mm->set_ctrl_pressed((wParam & MK_CONTROL) != 0); mm->set_shift_pressed((wParam & MK_SHIFT) != 0); mm->set_alt_pressed(alt_mem); @@ -2859,9 +2927,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y))); old_x = mm->get_position().x; old_y = mm->get_position().y; - if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) { - Input::get_singleton()->parse_input_event(mm); + + if (receiving_window_id != window_id) { + // Adjust event position relative to window distance when event is sent to a different window. + mm->set_position(mm->get_position() - window_get_position(receiving_window_id) + window_get_position(window_id)); + mm->set_global_position(mm->get_position()); } + Input::get_singleton()->parse_input_event(mm); } break; case WM_LBUTTONDOWN: @@ -3466,7 +3538,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, DWORD dwExStyle; DWORD dwStyle; - _get_window_style(window_id_counter == MAIN_WINDOW_ID, (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN, p_flags & WINDOW_FLAG_BORDERLESS_BIT, !(p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT), p_mode == WINDOW_MODE_MAXIMIZED, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT), dwStyle, dwExStyle); + _get_window_style(window_id_counter == MAIN_WINDOW_ID, (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN, p_flags & WINDOW_FLAG_BORDERLESS_BIT, !(p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT), p_mode == WINDOW_MODE_MAXIMIZED, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) | (p_flags & WINDOW_FLAG_POPUP), dwStyle, dwExStyle); RECT WindowRect; @@ -3559,6 +3631,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, windows.erase(id); ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create an OpenGL window."); } + window_set_vsync_mode(p_vsync_mode, id); } #endif @@ -3704,7 +3777,7 @@ void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) { } } -DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { +DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { drop_events = false; key_event_pos = 0; @@ -3856,9 +3929,15 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win (screen_get_size(0).width - p_resolution.width) / 2, (screen_get_size(0).height - p_resolution.height) / 2); + if (p_position != nullptr) { + window_position = *p_position; + } + WindowID main_window = _create_window(p_mode, p_vsync_mode, 0, Rect2i(window_position, p_resolution)); ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window."); + joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd); + for (int i = 0; i < WINDOW_FLAG_MAX; i++) { if (p_flags & (1 << i)) { window_set_flag(WindowFlags(i), true, main_window); @@ -3898,8 +3977,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win _update_real_mouse_position(MAIN_WINDOW_ID); - joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd); - r_error = OK; static_cast<OS_Windows *>(OS::get_singleton())->set_main_window(windows[MAIN_WINDOW_ID].hWnd); @@ -3919,12 +3996,24 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() { return drivers; } -DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { - DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_resolution, r_error)); +DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, Error &r_error) { + DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, r_error)); if (r_error != OK) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported Vulkan or OpenGL versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", - "Unable to initialize Video driver"); + if (p_rendering_driver == "vulkan") { + String executable_name = OS::get_singleton()->get_executable_path().get_file(); + OS::get_singleton()->alert("Your video card driver does not support the selected Vulkan version.\n" + "Please try updating your GPU driver or try using the OpenGL 3 driver.\n" + "You can enable the OpenGL 3 driver by starting the engine from the\n" + "command line with the command:\n'./" + + executable_name + " --rendering-driver opengl3'.\n " + "If you have updated your graphics drivers recently, try rebooting.", + "Unable to initialize Video driver"); + } else { + OS::get_singleton()->alert("Your video card driver does not support the selected OpenGL version.\n" + "Please try updating your GPU driver.\n" + "If you have updated your graphics drivers recently, try rebooting.", + "Unable to initialize Video driver"); + } } return ds; } |