diff --git a/server/.vscode/settings.json b/server/.vscode/settings.json index 44a83b8a..74edea8b 100644 --- a/server/.vscode/settings.json +++ b/server/.vscode/settings.json @@ -2,5 +2,6 @@ "files.exclude": {}, "search.exclude": { "fmt": true, - } + }, + "liveServer.settings.port": 5501 } \ No newline at end of file diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index c03324e9..ba6cf16c 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -7,7 +7,7 @@ project(${PROJECT_NAME} VERSION 1.0) # Boost set(Boost_ROOT "C:/Users/SonnyCalcr/scoop/apps/boost/1.87.0") set (Boost_USE_STATIC_LIBS ON) -find_package(Boost REQUIRED COMPONENTS locale) +find_package(Boost REQUIRED COMPONENTS locale json) # fmt and spdlog set(CMAKE_PREFIX_PATH "C:/Users/SonnyCalcr/EDisk/CppCodes/Libraries/AllLibs") @@ -24,9 +24,9 @@ add_definitions( /DUNICODE=1 ) -# add_definitions( -# /DFANY_DEBUG=1 -# ) +add_definitions( + /DFANY_DEBUG=1 +) include_directories("./src/") @@ -56,4 +56,4 @@ set_target_properties(${PROJECT_NAME} PROPERTIES VS_GLOBAL_WebView2LoaderPrefere set_target_properties(${PROJECT_NAME} PROPERTIES VS_USER_PROPS "${CMAKE_SOURCE_DIR}/FanIME_UI.props") set_target_properties(${PROJECT_NAME} PROPERTIES VS_PACKAGE_REFERENCES "Microsoft.Web.WebView2_1.0.3124.44;Microsoft.Windows.ImplementationLibrary_1.0.240803.1") -target_link_libraries(${PROJECT_NAME} fmt::fmt spdlog::spdlog Boost::locale) \ No newline at end of file +target_link_libraries(${PROJECT_NAME} fmt::fmt spdlog::spdlog Boost::locale Boost::json) \ No newline at end of file diff --git a/server/html/default-themes/body/horizontal_candidate_window_dark.html b/server/html/default-themes/body/horizontal_candidate_window_dark.html index 1cf569a1..0edc97fc 100644 --- a/server/html/default-themes/body/horizontal_candidate_window_dark.html +++ b/server/html/default-themes/body/horizontal_candidate_window_dark.html @@ -1,4 +1,4 @@ -
+
{0}
diff --git a/server/html/default-themes/body/vertical_candidate_window_dark.html b/server/html/default-themes/body/vertical_candidate_window_dark.html index 1cf569a1..0edc97fc 100644 --- a/server/html/default-themes/body/vertical_candidate_window_dark.html +++ b/server/html/default-themes/body/vertical_candidate_window_dark.html @@ -1,4 +1,4 @@ -
+
{0}
diff --git a/server/html/default-themes/horizontal_candidate_window_dark.html b/server/html/default-themes/horizontal_candidate_window_dark.html index 2f17d976..262685ef 100644 --- a/server/html/default-themes/horizontal_candidate_window_dark.html +++ b/server/html/default-themes/horizontal_candidate_window_dark.html @@ -80,7 +80,7 @@ -
+
ni'uo
diff --git a/server/html/default-themes/vertical_candidate_window_dark.html b/server/html/default-themes/vertical_candidate_window_dark.html index 47936cc6..28b42f11 100644 --- a/server/html/default-themes/vertical_candidate_window_dark.html +++ b/server/html/default-themes/vertical_candidate_window_dark.html @@ -83,7 +83,7 @@ -
+
ni'uo
diff --git a/server/src/defines/base_structures.h b/server/src/defines/base_structures.h new file mode 100644 index 00000000..d6a975cf --- /dev/null +++ b/server/src/defines/base_structures.h @@ -0,0 +1,9 @@ +#pragma once + +struct MonitorCoordinates +{ + int left = 0; + int top = 0; + int right = 0; + int bottom = 0; +}; \ No newline at end of file diff --git a/server/src/utils/webview_utils.cpp b/server/src/utils/webview_utils.cpp index 368ec981..29c65e4f 100644 --- a/server/src/utils/webview_utils.cpp +++ b/server/src/utils/webview_utils.cpp @@ -1,6 +1,9 @@ #include "webview_utils.h" #include "spdlog/spdlog.h" #include "utils/common_utils.h" +#include + +namespace json = boost::json; void MeasureDomUpdateTime(ComPtr webview) { @@ -16,4 +19,62 @@ void MeasureDomUpdateTime(ComPtr webview) auto duration = std::chrono::duration_cast(end - start); std::wstring message = L"DOM update time: " + std::to_wstring(duration.count()) + L" μs"; spdlog::info(wstring_to_string(message)); +} + +std::pair ParseDivSize(const std::wstring &jsonResult) +{ + std::string jsonStr = wstring_to_string(jsonResult); +#ifdef FANY_DEBUG + spdlog::info("Div size: {}", jsonStr); +#endif + auto size = std::make_pair(0.0, 0.0); + try + { + json::value parsed = json::parse(jsonStr); + if (parsed.is_string()) + { + parsed = json::parse(parsed.as_string()); + } + double width = parsed.at("width").is_int64() // + ? parsed.at("width").as_int64() // + : parsed.at("width").as_double(); // + double height = parsed.at("height").is_int64() // + ? parsed.at("height").as_int64() // + : parsed.at("height").as_double(); // + size = std::make_pair(width, height); + } + catch (const std::exception &e) + { +#ifdef FANY_DEBUG + spdlog::error("Failed to parse JSON: {}", e.what()); +#endif + } + return size; +} + +void GetContainerSize(ComPtr webview, std::function)> callback) +{ + std::wstring script = LR"( + (function() { + var rect = document.querySelector("#container").getBoundingClientRect(); + return JSON.stringify({width: rect.width, height: rect.height}); + })(); + )"; + webview->ExecuteScript( // + script.c_str(), // + Callback([callback](HRESULT errorCode, LPCWSTR result) -> HRESULT { + std::pair size; + if (SUCCEEDED(errorCode) && result) + { + size = ParseDivSize(result); + } + else + { +#ifdef FANY_DEBUG + spdlog::error("Failed to get container size."); +#endif + } + callback(size); + return S_OK; + }).Get()); } \ No newline at end of file diff --git a/server/src/utils/webview_utils.h b/server/src/utils/webview_utils.h index 9f93a71e..01a1cd56 100644 --- a/server/src/utils/webview_utils.h +++ b/server/src/utils/webview_utils.h @@ -1,5 +1,8 @@ #pragma once #include "webview2/candidate_window_webview2.h" +#include -void MeasureDomUpdateTime(ComPtr); \ No newline at end of file +void MeasureDomUpdateTime(ComPtr); + +void GetContainerSize(ComPtr, std::function)>); \ No newline at end of file diff --git a/server/src/utils/window_utils.cpp b/server/src/utils/window_utils.cpp new file mode 100644 index 00000000..ed2b22bc --- /dev/null +++ b/server/src/utils/window_utils.cpp @@ -0,0 +1,70 @@ +#include "window_utils.h" +#include "spdlog/spdlog.h" + +FLOAT GetWindowScale(HWND hwnd) +{ + UINT dpi = GetDpiForWindow(hwnd); + FLOAT scale = dpi / 96.0f; + return scale; +} + +//+--------------------------------------------------------------------------- +// +// GetMonitorCoordinates +// +//---------------------------------------------------------------------------- + +MonitorCoordinates GetMonitorCoordinates() +{ + MonitorCoordinates coordinates; + HWND hwnd = GetForegroundWindow(); + FLOAT scale = GetWindowScale(hwnd); + HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + if (!hMonitor) + { +#ifdef FANY_DEBUG + spdlog::error("Failed to get monitor."); +#endif + return coordinates; + } + + MONITORINFO monitorInfo = {sizeof(monitorInfo)}; + if (GetMonitorInfo(hMonitor, &monitorInfo)) + { + int width = (monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left) * scale; + int height = (monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top) * scale; + coordinates.left = monitorInfo.rcMonitor.left * scale; + coordinates.top = monitorInfo.rcMonitor.top * scale; + coordinates.right = coordinates.left + width; + coordinates.bottom = coordinates.top + height; + } + else + { +#ifdef FANY_DEBUG + spdlog::error("Failed to get monitor info."); +#endif + } + return coordinates; +} + +int AdjustCandidateWindowPosition(POINT &point) +{ + MonitorCoordinates coordinates = GetMonitorCoordinates(); + if (point.x < coordinates.left) + { + point.x = coordinates.left + 2; + } + if (point.y < coordinates.top) + { + point.y = coordinates.top + 2; + } + if (point.x > coordinates.right) + { + point.x = coordinates.right - 2; + } + if (point.y > coordinates.bottom) + { + point.y = coordinates.bottom - 2; + } + return 0; +} \ No newline at end of file diff --git a/server/src/utils/window_utils.h b/server/src/utils/window_utils.h new file mode 100644 index 00000000..5df55eec --- /dev/null +++ b/server/src/utils/window_utils.h @@ -0,0 +1,9 @@ +#include "defines/base_structures.h" +#include + + +FLOAT GetWindowScale(HWND); + +MonitorCoordinates GetMonitorCoordinates(); + +int AdjustCandidateWindowPosition(POINT &); \ No newline at end of file diff --git a/server/src/window/candidate_window.cpp b/server/src/window/candidate_window.cpp index 4761e3f5..e47f7402 100644 --- a/server/src/window/candidate_window.cpp +++ b/server/src/window/candidate_window.cpp @@ -2,8 +2,10 @@ #include "defines/defines.h" #include "spdlog/spdlog.h" #include "utils/common_utils.h" +#include "utils/webview_utils.h" #include "webview2/candidate_window_webview2.h" #include +#include LRESULT RegisterCandidateWindowMessage() { @@ -129,6 +131,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) (246 + 15) * 1.5, // TRUE // ); // +#ifdef FANY_DEBUG + std::string windowPos = std::to_string(pt->x) + "," + std::to_string(pt->y); + spdlog::info(windowPos); + GetContainerSize(webview, [](std::pair size) { + spdlog::info("Container size: ({}, {})", size.first, size.second); + }); +#endif } else if (pcds->dwData == 1) {