| Index: ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
| diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
| index fd8de8f35884f4fe7935cc83f5a7190b1427118b..0f9765172ab8281cfa9c6f677902cee4a4d82a77 100644
|
| --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
| +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
|
| @@ -17,6 +17,7 @@
|
| #include "ui/base/win/shell.h"
|
| #include "ui/compositor/compositor_constants.h"
|
| #include "ui/compositor/paint_context.h"
|
| +#include "ui/display/display.h"
|
| #include "ui/display/win/dpi.h"
|
| #include "ui/display/win/screen_win.h"
|
| #include "ui/gfx/geometry/insets.h"
|
| @@ -61,6 +62,86 @@ void InsetBottomRight(gfx::Rect* rect, const gfx::Vector2d& vector) {
|
| rect->Inset(0, 0, vector.x(), vector.y());
|
| }
|
|
|
| +// https://blogs.msdn.microsoft.com/oldnewthing/20131017-00/?p=2903.
|
| +bool UnadjustWindowRectEx(RECT* rect, DWORD style, BOOL menu, DWORD ex_style) {
|
| + RECT adjust_rect;
|
| + SetRectEmpty(&adjust_rect);
|
| + bool success = !!AdjustWindowRectEx(&adjust_rect, style, menu, ex_style);
|
| + if (success) {
|
| + rect->left -= adjust_rect.left;
|
| + rect->top -= adjust_rect.top;
|
| + rect->right -= adjust_rect.right;
|
| + rect->bottom -= adjust_rect.bottom;
|
| + }
|
| + return success;
|
| +}
|
| +
|
| +double GetIntegralMultipleForDSF(double dsf) {
|
| + if (static_cast<int>(dsf) == dsf)
|
| + return dsf;
|
| + // Rather than calculate an integral multiple here, we only handle common
|
| + // DSFs; this is done so that if we somehow end up with a strange
|
| + // non-integral-dividing one, we don't cause the window to resize in huge
|
| + // chunks. This table is effectively the numerator of the DSF expressed as a
|
| + // reduced improper fraction.
|
| + static const struct { double dsf; double multiple; } kKnownFactors[] = {
|
| + // def GCD(a, b): return a if b == 0 else GCD(b, a % b)
|
| + // for i in range(125, 351, 25):
|
| + // if i / 100.0 == i // 100: continue
|
| + // gcd = GCD(i, 100)
|
| + // print '{ %f, %d }, ' % (i / 100.0, i / gcd)
|
| + { 1.250000, 5 },
|
| + { 1.500000, 3 },
|
| + { 1.750000, 7 },
|
| + { 2.250000, 9 },
|
| + { 2.500000, 5 },
|
| + { 2.750000, 11 },
|
| + { 3.250000, 13 },
|
| + { 3.500000, 7 },
|
| + };
|
| + for (const auto& element : kKnownFactors) {
|
| + if (element.dsf == dsf)
|
| + return element.multiple;
|
| + }
|
| + return 1.0;
|
| +}
|
| +
|
| +void EnsureIntegralMultipleOfDeviceScaleFactor(double dsf,
|
| + gfx::Rect* rect,
|
| + UINT edge,
|
| + DWORD style,
|
| + DWORD ex_style) {
|
| + RECT client = rect->ToRECT();
|
| + if (UnadjustWindowRectEx(&client, style, false, ex_style)) {
|
| + // Adjust the client size so that it's an integral multiple of DSF.
|
| + const double multiple = GetIntegralMultipleForDSF(dsf);
|
| +
|
| + const double adjusted_width =
|
| + floor((static_cast<double>(client.right) - client.left) / multiple) *
|
| + multiple;
|
| + if (edge == 0 || edge == WMSZ_RIGHT || edge == WMSZ_TOPRIGHT ||
|
| + edge == WMSZ_BOTTOMRIGHT) {
|
| + client.right = client.left + static_cast<int>(adjusted_width);
|
| + }
|
| + if (edge == WMSZ_LEFT || edge == WMSZ_TOPLEFT || edge == WMSZ_BOTTOMLEFT)
|
| + client.left = client.right - static_cast<int>(adjusted_width);
|
| +
|
| + const double adjusted_height =
|
| + floor((static_cast<double>(client.bottom) - client.top) / multiple) *
|
| + multiple;
|
| + if (edge == 0 || edge == WMSZ_BOTTOM || edge == WMSZ_BOTTOMLEFT ||
|
| + edge == WMSZ_BOTTOMRIGHT) {
|
| + client.bottom = client.top + static_cast<int>(adjusted_height);
|
| + }
|
| + if (edge == WMSZ_TOP || edge == WMSZ_TOPLEFT || edge == WMSZ_TOPRIGHT)
|
| + client.top = client.bottom - static_cast<int>(adjusted_height);
|
| +
|
| + // Convert client size back to window, and store into rect.
|
| + if (AdjustWindowRectEx(&client, style, false, ex_style))
|
| + *rect = gfx::Rect(client);
|
| + }
|
| +}
|
| +
|
| } // namespace
|
|
|
| DEFINE_WINDOW_PROPERTY_KEY(aura::Window*, kContentWindowForRootWindow, NULL);
|
| @@ -174,6 +255,17 @@ void DesktopWindowTreeHostWin::OnNativeWidgetCreated(
|
| SetWindowTransparency();
|
| }
|
|
|
| +void DesktopWindowTreeHostWin::OnNativeWidgetInitDone() {
|
| + gfx::Rect pixel_bounds = message_handler_->GetWindowBoundsInScreen();
|
| + display::Display display =
|
| + display::Screen::GetScreen()->GetDisplayNearestWindow(
|
| + GetWidget()->GetNativeView());
|
| + EnsureIntegralMultipleOfDeviceScaleFactor(
|
| + display.device_scale_factor(), &pixel_bounds, 0,
|
| + message_handler_->window_style(), message_handler_->window_ex_style());
|
| + SetBounds(pixel_bounds);
|
| +}
|
| +
|
| std::unique_ptr<corewm::Tooltip> DesktopWindowTreeHostWin::CreateTooltip() {
|
| DCHECK(!tooltip_);
|
| tooltip_ = new corewm::TooltipWin(GetAcceleratedWidget());
|
| @@ -837,6 +929,18 @@ void DesktopWindowTreeHostWin::HandleKeyEvent(ui::KeyEvent* event) {
|
| GetInputMethod()->DispatchKeyEvent(event);
|
| }
|
|
|
| +void DesktopWindowTreeHostWin::HandleSizing(UINT edge, RECT* rect) {
|
| + display::Display display =
|
| + display::Screen::GetScreen()->GetDisplayNearestWindow(
|
| + GetWidget()->GetNativeView());
|
| + DWORD style = GetWindowLong(GetHWND(), GWL_STYLE);
|
| + DWORD ex_style = GetWindowLong(GetHWND(), GWL_EXSTYLE);
|
| + gfx::Rect gfx_rect(*rect);
|
| + EnsureIntegralMultipleOfDeviceScaleFactor(display.device_scale_factor(),
|
| + &gfx_rect, edge, style, ex_style);
|
| + *rect = gfx_rect.ToRECT();
|
| +}
|
| +
|
| void DesktopWindowTreeHostWin::HandleTouchEvent(
|
| const ui::TouchEvent& event) {
|
| // HWNDMessageHandler asynchronously processes touch events. Because of this
|
|
|