Commit eaf0a6b2 authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

wm: Dragged windows position takes into account caption container.

When dragging a maximized window, the window may resize. We try to
position the window so that the ratio between origin and event
location and width remains equal.

The caption buttons have the same size even if the window shrinks
though, so if the original click was near the caption buttons, the
ratio result may end up on top of the caption buttons. This CL
addresses them by checking the position of the caption and shifting
the new window bounds such that the mouse will not be on top of the
caption buttons.

This won't have an effect on custom headers, as theres no way to
determine how large their caption area is.

Test: manual
Change-Id: I15b235dae773fe90283ffabf9daff0e4ac984e24
Fixed: 1082839
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2238415Reviewed-by: default avatarMitsuru Oshima (slow:gardening) <oshima@chromium.org>
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#779874}
parent 61a9134d
...@@ -88,6 +88,10 @@ class ASH_PUBLIC_EXPORT FrameHeader : public views::AnimationDelegateViews { ...@@ -88,6 +88,10 @@ class ASH_PUBLIC_EXPORT FrameHeader : public views::AnimationDelegateViews {
views::View* view() { return view_; } views::View* view() { return view_; }
FrameCaptionButtonContainerView* caption_button_container() {
return caption_button_container_;
}
protected: protected:
FrameHeader(views::Widget* target_widget, views::View* view); FrameHeader(views::Widget* target_widget, views::View* view);
...@@ -106,10 +110,6 @@ class ASH_PUBLIC_EXPORT FrameHeader : public views::AnimationDelegateViews { ...@@ -106,10 +110,6 @@ class ASH_PUBLIC_EXPORT FrameHeader : public views::AnimationDelegateViews {
void SetCaptionButtonContainer( void SetCaptionButtonContainer(
FrameCaptionButtonContainerView* caption_button_container); FrameCaptionButtonContainerView* caption_button_container);
FrameCaptionButtonContainerView* caption_button_container() {
return caption_button_container_;
}
Mode mode() const { return mode_; } Mode mode() const { return mode_; }
const gfx::SlideAnimation& activation_animation() { const gfx::SlideAnimation& activation_animation() {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "ash/wm/window_resizer.h" #include "ash/wm/window_resizer.h"
#include "ash/public/cpp/frame_header.h"
#include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_positioning_utils.h"
#include "ash/wm/window_state.h" #include "ash/wm/window_state.h"
#include "ash/wm/window_util.h" #include "ash/wm/window_util.h"
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
#include "ui/display/screen.h" #include "ui/display/screen.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/gfx/presentation_feedback.h" #include "ui/gfx/presentation_feedback.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/window_resize_utils.h" #include "ui/views/window/window_resize_utils.h"
#include "ui/wm/core/coordinate_conversion.h" #include "ui/wm/core/coordinate_conversion.h"
...@@ -313,18 +315,60 @@ gfx::Point WindowResizer::GetOriginForDrag(int delta_x, ...@@ -313,18 +315,60 @@ gfx::Point WindowResizer::GetOriginForDrag(int delta_x,
// modify the origin so that the cursor remains within the dragged window. // modify the origin so that the cursor remains within the dragged window.
// The ratio of the new origin to the new location should match the ratio // The ratio of the new origin to the new location should match the ratio
// from the initial origin to the initial location. // from the initial origin to the initial location.
if (!details().restore_bounds_in_parent.IsEmpty()) { const gfx::Rect restore_bounds = details().restore_bounds_in_parent;
// The ratios that should match is the (drag location x - bounds origin x) / if (restore_bounds.IsEmpty())
// bounds width. return origin;
const float ratio = (details().initial_location_in_parent.x() -
float{details().initial_bounds_in_parent.x()}) / // The ratios that should match is the (drag location x - bounds origin x) /
details().initial_bounds_in_parent.width(); // bounds width.
const int new_origin_x = const float ratio = (details().initial_location_in_parent.x() -
gfx::ToRoundedInt(event_location.x() - float{details().initial_bounds_in_parent.x()}) /
ratio * details().restore_bounds_in_parent.width()); details().initial_bounds_in_parent.width();
origin.set_x(new_origin_x); int new_origin_x =
} gfx::ToRoundedInt(event_location.x() - ratio * restore_bounds.width());
origin.set_x(new_origin_x);
// Windows may not have a widget in tests.
auto* widget = views::Widget::GetWidgetForNativeWindow(GetTarget());
if (!widget)
return origin;
// |widget| may have a custom frame, |header| will be null in this case.
auto* header = FrameHeader::Get(widget);
if (!header)
return origin;
// Compute the available bounds based on the header local bounds. These bounds
// are from the previous layout and do not match |restore_bounds| yet.
gfx::Rect header_bounds = header->view()->GetLocalBounds();
header_bounds.set_height(header->GetHeaderHeight());
gfx::Rect available_bounds = header_bounds;
auto* back_button = header->GetBackButton();
auto* caption_button_container = header->caption_button_container();
if (back_button)
available_bounds.Subtract(back_button->bounds());
if (caption_button_container)
available_bounds.Subtract(caption_button_container->bounds());
// Calculate the new expected available header left and right bounds. The new
// header will still are |new_origin_x| with width |restore_bounds.width()|.
// The available region subtracts the control buttons.
const int header_left =
new_origin_x + (available_bounds.x() - header_bounds.x());
const int header_right = new_origin_x + restore_bounds.width() -
(header_bounds.right() - available_bounds.right());
// If |event_location| x falls outside |available_bounds|, shift
// |new_origin_x| so that the new window bounds will not land on the any of
// the header buttons.
int shift = 0;
if (event_location.x() > header_right)
shift = event_location.x() - header_right;
else if (event_location.x() < header_left)
shift = event_location.x() - header_left;
new_origin_x += shift;
origin.set_x(new_origin_x);
return origin; return origin;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment