summaryrefslogtreecommitdiffstats
path: root/platform/windows/display_server_windows.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/windows/display_server_windows.cpp')
-rw-r--r--platform/windows/display_server_windows.cpp150
1 files changed, 102 insertions, 48 deletions
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index ffa3840181..e300bd1c47 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -30,6 +30,7 @@
#include "display_server_windows.h"
+#include "drop_target_windows.h"
#include "os_windows.h"
#include "wgl_detect_version.h"
@@ -67,6 +68,18 @@
#define DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 19
#endif
+#ifndef DWMWA_WINDOW_CORNER_PREFERENCE
+#define DWMWA_WINDOW_CORNER_PREFERENCE 33
+#endif
+
+#ifndef DWMWCP_DEFAULT
+#define DWMWCP_DEFAULT 0
+#endif
+
+#ifndef DWMWCP_DONOTROUND
+#define DWMWCP_DONOTROUND 1
+#endif
+
#define WM_INDICATOR_CALLBACK_MESSAGE (WM_USER + 1)
#if defined(__GNUC__)
@@ -117,6 +130,7 @@ bool DisplayServerWindows::has_feature(Feature p_feature) const {
case FEATURE_NATIVE_DIALOG:
case FEATURE_NATIVE_DIALOG_INPUT:
case FEATURE_NATIVE_DIALOG_FILE:
+ case FEATURE_NATIVE_DIALOG_FILE_EXTRA:
case FEATURE_SWAP_BUFFERS:
case FEATURE_KEEP_SCREEN_ON:
case FEATURE_TEXT_TO_SPEECH:
@@ -304,8 +318,8 @@ public:
}
// IFileDialogEvents methods
- HRESULT STDMETHODCALLTYPE OnFileOk(IFileDialog *) { return S_OK; };
- HRESULT STDMETHODCALLTYPE OnFolderChange(IFileDialog *) { return S_OK; };
+ HRESULT STDMETHODCALLTYPE OnFileOk(IFileDialog *) { return S_OK; }
+ HRESULT STDMETHODCALLTYPE OnFolderChange(IFileDialog *) { return S_OK; }
HRESULT STDMETHODCALLTYPE OnFolderChanging(IFileDialog *p_pfd, IShellItem *p_item) {
if (root.is_empty()) {
@@ -324,11 +338,11 @@ public:
return S_OK;
}
- HRESULT STDMETHODCALLTYPE OnHelp(IFileDialog *) { return S_OK; };
- HRESULT STDMETHODCALLTYPE OnSelectionChange(IFileDialog *) { return S_OK; };
- HRESULT STDMETHODCALLTYPE OnShareViolation(IFileDialog *, IShellItem *, FDE_SHAREVIOLATION_RESPONSE *) { return S_OK; };
- HRESULT STDMETHODCALLTYPE OnTypeChange(IFileDialog *pfd) { return S_OK; };
- HRESULT STDMETHODCALLTYPE OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; };
+ HRESULT STDMETHODCALLTYPE OnHelp(IFileDialog *) { return S_OK; }
+ HRESULT STDMETHODCALLTYPE OnSelectionChange(IFileDialog *) { return S_OK; }
+ HRESULT STDMETHODCALLTYPE OnShareViolation(IFileDialog *, IShellItem *, FDE_SHAREVIOLATION_RESPONSE *) { return S_OK; }
+ HRESULT STDMETHODCALLTYPE OnTypeChange(IFileDialog *pfd) { return S_OK; }
+ HRESULT STDMETHODCALLTYPE OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; }
// IFileDialogControlEvents methods
HRESULT STDMETHODCALLTYPE OnItemSelected(IFileDialogCustomize *p_pfdc, DWORD p_ctl_id, DWORD p_item_idx) {
@@ -338,14 +352,14 @@ public:
return S_OK;
}
- HRESULT STDMETHODCALLTYPE OnButtonClicked(IFileDialogCustomize *, DWORD) { return S_OK; };
+ HRESULT STDMETHODCALLTYPE OnButtonClicked(IFileDialogCustomize *, DWORD) { return S_OK; }
HRESULT STDMETHODCALLTYPE OnCheckButtonToggled(IFileDialogCustomize *p_pfdc, DWORD p_ctl_id, BOOL p_checked) {
if (ctls.has(p_ctl_id)) {
selected[ctls[p_ctl_id]] = (bool)p_checked;
}
return S_OK;
}
- HRESULT STDMETHODCALLTYPE OnControlActivating(IFileDialogCustomize *, DWORD) { return S_OK; };
+ HRESULT STDMETHODCALLTYPE OnControlActivating(IFileDialogCustomize *, DWORD) { return S_OK; }
Dictionary get_selected() {
return selected;
@@ -491,7 +505,7 @@ void DisplayServerWindows::_thread_fd_monitor(void *p_ud) {
}
if (filter_names.is_empty()) {
filter_exts.push_back(String("*.*").utf16());
- filter_names.push_back(RTR("All Files").utf16());
+ filter_names.push_back((RTR("All Files") + " (*)").utf16());
}
Vector<COMDLG_FILTERSPEC> filters;
@@ -722,7 +736,7 @@ Error DisplayServerWindows::_file_dialog_with_options_show(const String &p_title
GetWindowRect(fd->hwnd_owner, &crect);
fd->wrect = Rect2i(crect.left, crect.top, crect.right - crect.left, crect.bottom - crect.top);
} else {
- fd->hwnd_owner = 0;
+ fd->hwnd_owner = nullptr;
fd->wrect = Rect2i(CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT);
}
fd->appid = appname;
@@ -1483,6 +1497,9 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
if (p_flags & WINDOW_FLAG_ALWAYS_ON_TOP_BIT && p_mode != WINDOW_MODE_FULLSCREEN && p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
wd.always_on_top = true;
}
+ if (p_flags & WINDOW_FLAG_SHARP_CORNERS_BIT) {
+ wd.sharp_corners = true;
+ }
if (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) {
wd.no_focus = true;
}
@@ -1601,11 +1618,17 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
}
#endif
- if ((tablet_get_current_driver() == "wintab") && wintab_available && windows[p_window].wtctx) {
- wintab_WTClose(windows[p_window].wtctx);
- windows[p_window].wtctx = nullptr;
+ if ((tablet_get_current_driver() == "wintab") && wintab_available && wd.wtctx) {
+ wintab_WTClose(wd.wtctx);
+ wd.wtctx = nullptr;
+ }
+
+ if (wd.drop_target != nullptr) {
+ RevokeDragDrop(wd.hWnd);
+ wd.drop_target->Release();
}
- DestroyWindow(windows[p_window].hWnd);
+
+ DestroyWindow(wd.hWnd);
windows.erase(p_window);
if (last_focused_window == p_window) {
@@ -1650,6 +1673,18 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type,
}
return 0;
}
+ case EGL_DISPLAY: {
+ if (gl_manager_angle) {
+ return (int64_t)gl_manager_angle->get_display(p_window);
+ }
+ return 0;
+ }
+ case EGL_CONFIG: {
+ if (gl_manager_angle) {
+ return (int64_t)gl_manager_angle->get_config(p_window);
+ }
+ return 0;
+ }
#endif
default: {
return 0;
@@ -1703,7 +1738,14 @@ void DisplayServerWindows::window_set_drop_files_callback(const Callable &p_call
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
- windows[p_window].drop_files_callback = p_callable;
+ WindowData &window_data = windows[p_window];
+
+ window_data.drop_files_callback = p_callable;
+
+ if (window_data.drop_target == nullptr) {
+ window_data.drop_target = memnew(DropTargetWindows(&window_data));
+ ERR_FAIL_COND(RegisterDragDrop(window_data.hWnd, window_data.drop_target) != S_OK);
+ }
}
void DisplayServerWindows::window_set_title(const String &p_title, WindowID p_window) {
@@ -2297,6 +2339,12 @@ void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, W
wd.always_on_top = p_enabled;
_update_window_style(p_window);
} break;
+ case WINDOW_FLAG_SHARP_CORNERS: {
+ wd.sharp_corners = p_enabled;
+ DWORD value = wd.sharp_corners ? DWMWCP_DONOTROUND : DWMWCP_DEFAULT;
+ ::DwmSetWindowAttribute(wd.hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &value, sizeof(value));
+ _update_window_style(p_window);
+ } break;
case WINDOW_FLAG_TRANSPARENT: {
if (p_enabled) {
// Enable per-pixel alpha.
@@ -3196,6 +3244,10 @@ void DisplayServerWindows::process_events() {
}
_THREAD_SAFE_UNLOCK_
+ if (tts) {
+ tts->process_events();
+ }
+
if (!drop_events) {
_process_key_events();
Input::get_singleton()->flush_buffered_events();
@@ -3994,6 +4046,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
native_menu->_menu_activate(HMENU(lParam), (int)wParam);
} break;
case WM_CREATE: {
+ {
+ DWORD value = windows[window_id].sharp_corners ? DWMWCP_DONOTROUND : DWMWCP_DEFAULT;
+ ::DwmSetWindowAttribute(windows[window_id].hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &value, sizeof(value));
+ }
if (is_dark_mode_supported() && dark_title_available) {
BOOL value = is_dark_mode();
@@ -4740,9 +4796,12 @@ 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;
+ DisplayServer::WindowID receiving_window_id = window_id;
+ if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
+ receiving_window_id = _get_focused_window_or_popup();
+ if (receiving_window_id == INVALID_WINDOW_ID) {
+ receiving_window_id = window_id;
+ }
}
const BitField<WinKeyModifierMask> &mods = _get_mods();
@@ -5282,32 +5341,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
}
} break;
- case WM_DROPFILES: {
- HDROP hDropInfo = (HDROP)wParam;
- const int buffsize = 4096;
- WCHAR buf[buffsize];
-
- int fcount = DragQueryFileW(hDropInfo, 0xFFFFFFFF, nullptr, 0);
-
- Vector<String> files;
-
- for (int i = 0; i < fcount; i++) {
- DragQueryFileW(hDropInfo, i, buf, buffsize);
- String file = String::utf16((const char16_t *)buf);
- files.push_back(file);
- }
-
- if (files.size() && windows[window_id].drop_files_callback.is_valid()) {
- Variant v_files = files;
- const Variant *v_args[1] = { &v_files };
- Variant ret;
- Callable::CallError ce;
- windows[window_id].drop_files_callback.callp((const Variant **)&v_args, 1, ret, ce);
- if (ce.error != Callable::CallError::CALL_OK) {
- ERR_PRINT(vformat("Failed to execute drop files callback: %s.", Variant::get_callable_error_text(windows[window_id].drop_files_callback, v_args, 1, ce)));
- }
- }
- } break;
default: {
if (user_proc) {
return CallWindowProcW(user_proc, hWnd, uMsg, wParam, lParam);
@@ -5412,7 +5445,7 @@ void DisplayServerWindows::_process_key_events() {
k->set_physical_keycode(physical_keycode);
k->set_key_label(key_label);
k->set_unicode(fix_unicode(unicode));
- if (k->get_unicode() && ke.altgr) {
+ if (k->get_unicode() && ke.altgr && windows[ke.window_id].ime_active) {
k->set_alt_pressed(false);
k->set_ctrl_pressed(false);
}
@@ -5488,7 +5521,7 @@ void DisplayServerWindows::_process_key_events() {
}
k->set_unicode(fix_unicode(unicode));
}
- if (k->get_unicode() && ke.altgr) {
+ if (k->get_unicode() && ke.altgr && windows[ke.window_id].ime_active) {
k->set_alt_pressed(false);
k->set_ctrl_pressed(false);
}
@@ -5645,6 +5678,12 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
wd_transient_parent->transient_children.insert(id);
}
+ wd.sharp_corners = p_flags & WINDOW_FLAG_SHARP_CORNERS_BIT;
+ {
+ DWORD value = wd.sharp_corners ? DWMWCP_DONOTROUND : DWMWCP_DEFAULT;
+ ::DwmSetWindowAttribute(wd.hWnd, DWMWA_WINDOW_CORNER_PREFERENCE, &value, sizeof(value));
+ }
+
if (is_dark_mode_supported() && dark_title_available) {
BOOL value = is_dark_mode();
::DwmSetWindowAttribute(wd.hWnd, use_legacy_dark_mode_before_20H1 ? DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 : DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
@@ -6130,6 +6169,8 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
FreeLibrary(comctl32);
}
+ OleInitialize(nullptr);
+
memset(&wc, 0, sizeof(WNDCLASSEXW));
wc.cbSize = sizeof(WNDCLASSEXW);
wc.style = CS_OWNDC | CS_DBLCLKS;
@@ -6195,6 +6236,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
}
#endif
+#if defined(GLES3_ENABLED)
bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
if (failed && fallback_to_opengl3 && rendering_driver != "opengl3") {
memdelete(rendering_context);
@@ -6206,6 +6248,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
failed = false;
}
+#endif
if (failed) {
memdelete(rendering_context);
rendering_context = nullptr;
@@ -6369,7 +6412,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution), false, INVALID_WINDOW_ID);
- ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window.");
+ if (main_window == INVALID_WINDOW_ID) {
+ r_error = ERR_UNAVAILABLE;
+ ERR_FAIL_MSG("Failed to create main window.");
+ }
joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd);
@@ -6557,6 +6603,12 @@ DisplayServerWindows::~DisplayServerWindows() {
wintab_WTClose(windows[MAIN_WINDOW_ID].wtctx);
windows[MAIN_WINDOW_ID].wtctx = nullptr;
}
+
+ if (windows[MAIN_WINDOW_ID].drop_target != nullptr) {
+ RevokeDragDrop(windows[MAIN_WINDOW_ID].hWnd);
+ windows[MAIN_WINDOW_ID].drop_target->Release();
+ }
+
DestroyWindow(windows[MAIN_WINDOW_ID].hWnd);
}
@@ -6588,4 +6640,6 @@ DisplayServerWindows::~DisplayServerWindows() {
if (tts) {
memdelete(tts);
}
+
+ OleUninitialize();
}