-
-
Notifications
You must be signed in to change notification settings - Fork 228
[Windows] Use frameless window to implement fullscreen #456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Since window_manager depends on screen_retriever, on enter: if (Platform.isWindows &&
!await windowManager.isMaximized()) {
AppStorage().windowPos = await windowManager.getPosition();
AppStorage().windowSize = await windowManager.getSize();
var info = (await screenRetriever.getPrimaryDisplay());
await windowManager.setAsFrameless();
await windowManager.setPosition(Offset.zero);
await windowManager.setSize(info.size);
} else {
windowManager.setFullScreen(true);
} on exit: if (Platform.isWindows && !await windowManager.isMaximized()) {
windowManager.setSize(AppStorage().windowSize);
windowManager.setTitleBarStyle(TitleBarStyle.hidden);
windowManager.setPosition(AppStorage().windowPos);
} else {
windowManager.setFullScreen(false);
} It works well on my own project. (no flicker & freeze, native titlebar won't appear on enter/exit fullscreen) I tried edit the plugin c++ code like this: void WindowManager::SetFullScreen(const flutter::EncodableMap& args) {
bool isFullScreen =
std::get<bool>(args.at(flutter::EncodableValue("isFullScreen")));
HWND mainWindow = GetMainWindow();
// Previously inspired by how Chromium does this
// https://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/fullscreen_handler.cc?revision=247204&view=markup
// Instead, we use a modified implementation of how the media_kit package
// implements this (we got permission from the author, I believe)
// https://github.com./alexmercerind/media_kit/blob/1226bcff36eab27cb17d60c33e9c15ca489c1f06/media_kit_video/windows/utils.cc
// Save current window state if not already fullscreen.
if (!g_is_window_fullscreen) {
// Save current window information.
g_maximized_before_fullscreen = ::IsZoomed(mainWindow);
g_style_before_fullscreen = GetWindowLong(mainWindow, GWL_STYLE);
::GetWindowRect(mainWindow, &g_frame_before_fullscreen);
g_title_bar_style_before_fullscreen = title_bar_style_;
}
g_is_window_fullscreen = isFullScreen;
if (isFullScreen) { // Set to fullscreen
// ::SendMessage(mainWindow, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
if (!is_frameless_) {
auto monitor = MONITORINFO{};
auto placement = WINDOWPLACEMENT{};
monitor.cbSize = sizeof(MONITORINFO);
placement.length = sizeof(WINDOWPLACEMENT);
::GetWindowPlacement(mainWindow, &placement);
::GetMonitorInfo(
::MonitorFromWindow(mainWindow, MONITOR_DEFAULTTONEAREST), &monitor);
SetAsFrameless();
::SetWindowLongPtr(mainWindow, GWL_STYLE,
g_style_before_fullscreen & ~WS_OVERLAPPEDWINDOW);
::SetWindowPos(mainWindow, HWND_TOP, monitor.rcMonitor.left,
monitor.rcMonitor.top,
monitor.rcMonitor.right - monitor.rcMonitor.left,
monitor.rcMonitor.bottom - monitor.rcMonitor.top,
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
}
} else { // Restore from fullscreen
// if (!g_maximized_before_fullscreen)
// Restore();
::SetWindowLongPtr(mainWindow, GWL_STYLE,
g_style_before_fullscreen | WS_OVERLAPPEDWINDOW);
if (::IsZoomed(mainWindow)) {
// Refresh the parent mainWindow.
::SetWindowPos(mainWindow, nullptr, 0, 0, 0, 0,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
SWP_FRAMECHANGED);
auto rect = RECT{};
::GetClientRect(mainWindow, &rect);
auto flutter_view = ::FindWindowEx(mainWindow, nullptr,
kFlutterViewWindowClassName, nullptr);
::SetWindowPos(flutter_view, nullptr, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
SWP_NOACTIVATE | SWP_NOZORDER);
if (g_maximized_before_fullscreen)
PostMessage(mainWindow, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
} else {
// ::SetWindowPos(
// mainWindow, nullptr, g_frame_before_fullscreen.left,
// g_frame_before_fullscreen.top,
// g_frame_before_fullscreen.right - g_frame_before_fullscreen.left,
// g_frame_before_fullscreen.bottom - g_frame_before_fullscreen.top,
// SWP_NOACTIVATE | SWP_NOZORDER);
// SetSize
SetWindowPos(mainWindow, nullptr, 0, 0,
g_frame_before_fullscreen.right - g_frame_before_fullscreen.left,
g_frame_before_fullscreen.bottom - g_frame_before_fullscreen.top,
SWP_NOMOVE);
// SetTitlebarStyle
title_bar_style_ = g_title_bar_style_before_fullscreen;
is_frameless_ = false;
MARGINS margins = {0, 0, 0, 0};
RECT rect1;
GetWindowRect(mainWindow, &rect1);
DwmExtendFrameIntoClientArea(mainWindow, &margins);
SetWindowPos(mainWindow, nullptr, rect1.left, rect1.top, 0, 0,
SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE |
SWP_FRAMECHANGED);
// SetPosition
SetWindowPos(mainWindow, nullptr, g_frame_before_fullscreen.left,
g_frame_before_fullscreen.top, 0, 0,
SWP_NOSIZE);
}
}
} However, it only works fine on enter fullscreen (no flicker & freeze) but the native titlebar still appear momentarily on exit. flutter doctor output:
|
The current
setFullscreen()
function on Windows may show the native window border as described in #211 and the application content may flicker aftersetFullscreen(true)
, Sometimes it may freeze the UI.On windows, there is another way to make application fullscreen:
1.Set the application to use frameless window.
2.Set the window size to the screen size.
3.Make the window cover the whole screen.
The windows taskbar will automatically hide itself.
I use the window_size package to get screen size:
When the application is maximized, use the original way to set fullscreen.
This code to enter fullscreen mode works fine on my computer.
Could you provide an option to use this way to set fullscreen on windows?
The text was updated successfully, but these errors were encountered: