diff --git a/flutter/windows/runner/CMakeLists.txt b/flutter/windows/runner/CMakeLists.txt index 17411a8ab..2dbf0a973 100644 --- a/flutter/windows/runner/CMakeLists.txt +++ b/flutter/windows/runner/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" + "win32_desktop.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" diff --git a/flutter/windows/runner/main.cpp b/flutter/windows/runner/main.cpp index 5c55d1c28..cd9f386b1 100644 --- a/flutter/windows/runner/main.cpp +++ b/flutter/windows/runner/main.cpp @@ -7,6 +7,7 @@ #include #include +#include "win32_desktop.h" #include "flutter_window.h" #include "utils.h" @@ -126,8 +127,22 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); FlutterWindow window(project); - Win32Window::Point origin(10, 10); - Win32Window::Size size(800, 600); + + // Get primary monitor's work area. + Win32Window::Point workarea_origin(0, 0); + Win32Window::Size workarea_size(0, 0); + + Win32Desktop::GetWorkArea(workarea_origin, workarea_size); + + // Compute window bounds for default main window position: (10, 10) x(800, 600) + Win32Window::Point relative_origin(10, 10); + + Win32Window::Point origin(workarea_origin.x + relative_origin.x, workarea_origin.y + relative_origin.y); + Win32Window::Size size(800u, 600u); + + // Fit the window to the monitor's work area. + Win32Desktop::FitToWorkArea(origin, size); + std::wstring window_title; if (is_cm_page) { window_title = app_name + L" - Connection Manager"; diff --git a/flutter/windows/runner/win32_desktop.cpp b/flutter/windows/runner/win32_desktop.cpp new file mode 100644 index 000000000..566f883ec --- /dev/null +++ b/flutter/windows/runner/win32_desktop.cpp @@ -0,0 +1,77 @@ +#include "win32_desktop.h" + +#include + +#include + +namespace Win32Desktop +{ + void GetWorkArea(Win32Window::Point& origin, Win32Window::Size& size) + { + RECT windowRect; + + windowRect.left = origin.x; + windowRect.top = origin.y; + windowRect.right = origin.x + size.width; + windowRect.bottom = origin.y + size.height; + + HMONITOR hMonitor = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONEAREST); + + if (hMonitor == NULL) + hMonitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY); + + RECT workAreaRect; + bool haveWorkAreaRect = false; + + if (hMonitor != NULL) + { + MONITORINFO monitorInfo = {0}; + + monitorInfo.cbSize = sizeof(monitorInfo); + + if (GetMonitorInfoW(hMonitor, &monitorInfo)) + { + workAreaRect = monitorInfo.rcWork; + haveWorkAreaRect = true; + } + } + + if (!haveWorkAreaRect) + { + // I don't think this is possible, but just in case, some + // reasonably sane fallbacks. + workAreaRect.left = 0; + workAreaRect.top = 0; + workAreaRect.right = 1280; + workAreaRect.bottom = 1024 - 40; // default Windows 10 task bar height + } + + origin.x = workAreaRect.left; + origin.y = workAreaRect.top; + + size.width = workAreaRect.right - workAreaRect.left; + size.height = workAreaRect.bottom - workAreaRect.top; + } + + void FitToWorkArea(Win32Window::Point& origin, Win32Window::Size& size) + { + // Retrieve the work area of the monitor that contains or + // is closed to the supplied window bounds. + Win32Window::Point workarea_origin = origin; + Win32Window::Size workarea_size = size; + + GetWorkArea(workarea_origin, workarea_size); + + // Translate the window so that its top/left is inside the work area. + origin.x = std::max(origin.x, workarea_origin.x); + origin.y = std::max(origin.y, workarea_origin.y); + + // Crop the window if it extends past the bottom/right of the work area. + Win32Window::Point workarea_bottom_right( + workarea_origin.x + workarea_size.width, + workarea_origin.y + workarea_size.height); + + size.width = std::min(size.width, workarea_bottom_right.x - origin.x); + size.height = std::min(size.height, workarea_bottom_right.y - origin.y); + } +} diff --git a/flutter/windows/runner/win32_desktop.h b/flutter/windows/runner/win32_desktop.h new file mode 100644 index 000000000..3ed757fe0 --- /dev/null +++ b/flutter/windows/runner/win32_desktop.h @@ -0,0 +1,12 @@ +#ifndef RUNNER_WIN32_DESKTOP_H_ +#define RUNNER_WIN32_DESKTOP_H_ + +#include "win32_window.h" + +namespace Win32Desktop +{ + void GetWorkArea(Win32Window::Point& origin, Win32Window::Size& size); + void FitToWorkArea(Win32Window::Point& origin, Win32Window::Size& size); +} + +#endif // RUNNER_WIN32_DESKTOP_H_ \ No newline at end of file