Commit 7e9b5103 authored by Xiaoqian Dai's avatar Xiaoqian Dai Committed by Commit Bot

Allow browser dragging on the non-tabstrip caption area.

The dragging behavior is the same with dragging an app window from the
top of the screen. As it shares some same logic with dragging an app
window, these logic are extracted to TabletModeWindowDragDelegate.

See recorded video:
https://drive.google.com/open?id=1d6t7K-ZuxgpT57b-Mx5gMJ49IjMHX-9X

Bug: 823769
Test: SplitViewTabDraggingTest.OnlyAllowDraggingOnCaptionArea

Change-Id: I09d852ef9eefd1059f2be85fee52e1714b1968fd
Reviewed-on: https://chromium-review.googlesource.com/1150860
Commit-Queue: Xiaoqian Dai <xdai@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580004}
parent b870c2c6
......@@ -262,8 +262,6 @@ void ShelfLayoutManager::UpdateVisibilityState() {
SetState(SHELF_VISIBLE);
} else if (Shell::Get()->screen_pinning_controller()->IsPinned()) {
SetState(SHELF_HIDDEN);
} else if (IsDraggingWindowFromTopOfDisplay()) {
SetState(SHELF_VISIBLE);
} else {
// TODO(zelidrag): Verify shelf drag animation still shows on the device
// when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN.
......@@ -273,7 +271,9 @@ void ShelfLayoutManager::UpdateVisibilityState() {
switch (window_state) {
case wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN: {
if (IsShelfAutoHideForFullscreenMaximized()) {
if (IsDraggingWindowFromTopOrCaptionArea()) {
SetState(SHELF_VISIBLE);
} else if (IsShelfAutoHideForFullscreenMaximized()) {
SetState(SHELF_AUTO_HIDE);
} else if (IsShelfHiddenForFullscreen()) {
SetState(SHELF_HIDDEN);
......@@ -285,7 +285,9 @@ void ShelfLayoutManager::UpdateVisibilityState() {
break;
}
case wm::WORKSPACE_WINDOW_STATE_MAXIMIZED:
if (IsShelfAutoHideForFullscreenMaximized()) {
if (IsDraggingWindowFromTopOrCaptionArea()) {
SetState(SHELF_VISIBLE);
} else if (IsShelfAutoHideForFullscreenMaximized()) {
SetState(SHELF_AUTO_HIDE);
} else {
SetState(CalculateShelfVisibility());
......@@ -414,14 +416,21 @@ bool ShelfLayoutManager::ProcessGestureEvent(
return false;
}
bool ShelfLayoutManager::IsDraggingWindowFromTopOfDisplay() const {
bool ShelfLayoutManager::IsDraggingWindowFromTopOrCaptionArea() const {
// Currently dragging maximized or fullscreen window from the top or the
// caption area is only allowed in tablet mode.
if (!IsTabletModeEnabled())
return false;
// TODO(minch): Check active window directly if removed search field
// in overview mode. http://crbug.com/866679
auto windows = Shell::Get()->mru_window_tracker()->BuildMruWindowList();
for (auto* window : windows) {
wm::WindowState* window_state = wm::GetWindowState(window);
if (window_state && window_state->is_dragged() &&
window_state->drag_details()->window_component == HTCLIENT) {
(window_state->IsMaximized() || window_state->IsFullscreen()) &&
(window_state->drag_details()->window_component == HTCLIENT ||
window_state->drag_details()->window_component == HTCAPTION)) {
return true;
}
}
......
......@@ -138,8 +138,10 @@ class ASH_EXPORT ShelfLayoutManager
// be processed any further, false otherwise.
bool ProcessGestureEvent(const ui::GestureEvent& event_in_screen);
// Returns true if a window is being dragged from the top of the display.
bool IsDraggingWindowFromTopOfDisplay() const;
// Returns true if a maximized or fullscreen window is being dragged from the
// top of the display or from the caption area. Note currently for this case
// it's only allowed in tablet mode, not in laptop mode.
bool IsDraggingWindowFromTopOrCaptionArea() const;
// Overridden from wm::WmSnapToPixelLayoutManager:
void OnWindowResized() override;
......
......@@ -141,8 +141,8 @@ class ASH_EXPORT SplitViewController : public mojom::SplitViewController,
// Ends the split view mode.
void EndSplitView();
// Called when a window's tab(s) start/end being dragged around or other
// non-browser windows start/end being dragged from the top of the display.
// Called when a window (either it's browser window or an app window) start/
// end being dragged.
void OnWindowDragStarted(aura::Window* dragged_window);
void OnWindowDragEnded(aura::Window* dragged_window,
SnapPosition desired_snap_position,
......
......@@ -1582,27 +1582,35 @@ class SplitViewTabDraggingTest : public SplitViewControllerTest {
};
// Test that in tablet mode, we only allow dragging that happens on window
// caption area and tab-dragging is in process.
TEST_F(SplitViewTabDraggingTest, OnlyAllowDraggingOnTabs) {
// caption area.
TEST_F(SplitViewTabDraggingTest, OnlyAllowDraggingOnCaptionArea) {
const gfx::Rect bounds(0, 0, 400, 400);
std::unique_ptr<aura::Window> window(CreateWindow(bounds));
std::unique_ptr<WindowResizer> resizer =
CreateResizerForTest(window.get(), gfx::Point(), HTCAPTION);
EXPECT_FALSE(resizer.get());
SetIsInTabDragging(window.get(), /*is_dragging=*/true);
// Only dragging on HTCAPTION area is allowed.
resizer = CreateResizerForTest(window.get(), gfx::Point(), HTLEFT);
std::unique_ptr<WindowResizer> resizer =
CreateResizerForTest(window.get(), gfx::Point(), HTLEFT);
EXPECT_FALSE(resizer.get());
resizer = CreateResizerForTest(window.get(), gfx::Point(), HTRIGHT);
EXPECT_FALSE(resizer.get());
resizer = CreateResizerForTest(window.get(), gfx::Point(), HTCAPTION);
EXPECT_TRUE(resizer.get());
resizer->CompleteDrag();
resizer.reset();
// No matter if we're in tab-dragging process, as long as the drag happens on
// the caption area, it should be able to drag the window.
SetIsInTabDragging(window.get(), /*is_dragging=*/true);
resizer = CreateResizerForTest(window.get(), gfx::Point(), HTCAPTION);
EXPECT_TRUE(resizer.get());
resizer->CompleteDrag();
resizer.reset();
SetIsInTabDragging(window.get(), /*is_dragging=*/false);
resizer = CreateResizerForTest(window.get(), gfx::Point(), HTCAPTION);
EXPECT_FALSE(resizer.get());
EXPECT_TRUE(resizer.get());
resizer->CompleteDrag();
resizer.reset();
}
// Test that in tablet mode, if the dragging is from mouse event, the mouse
......
......@@ -4,8 +4,6 @@
#include "ash/wm/tablet_mode/tablet_mode_app_window_drag_controller.h"
#include "ash/root_window_controller.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shell.h"
#include "ash/wm/overview/window_grid.h"
#include "ash/wm/overview/window_selector_controller.h"
......@@ -87,72 +85,29 @@ bool TabletModeAppWindowDragController::DragWindowFromTop(
void TabletModeAppWindowDragController::StartWindowDrag(
ui::GestureEvent* event) {
initial_location_in_screen_ = GetEventLocationInScreen(event);
drag_delegate_->StartWindowDrag(static_cast<aura::Window*>(event->target()),
initial_location_in_screen_);
WindowSelectorController* window_selector_controller =
Shell::Get()->window_selector_controller();
DCHECK(window_selector_controller->IsSelecting());
WindowGrid* window_grid =
window_selector_controller->window_selector()->GetGridWithRootWindow(
drag_delegate_->dragged_window()->GetRootWindow());
const std::vector<std::unique_ptr<WindowSelectorItem>>& selector_items =
window_grid->window_list();
new_selector_item_bounds_ = selector_items.back().get()->target_bounds();
GetEventLocationInScreen(event));
}
void TabletModeAppWindowDragController::UpdateWindowDrag(
ui::GestureEvent* event) {
const gfx::Point location_in_screen(GetEventLocationInScreen(event));
UpdateDraggedWindow(location_in_screen);
drag_delegate_->ContinueWindowDrag(location_in_screen);
// Update the dragged window's tranform during dragging.
drag_delegate_->ContinueWindowDrag(
GetEventLocationInScreen(event),
TabletModeWindowDragDelegate::UpdateDraggedWindowType::UPDATE_TRANSFORM);
}
void TabletModeAppWindowDragController::EndWindowDrag(
ui::GestureEvent* event,
wm::WmToplevelWindowEventHandler::DragResult result) {
const gfx::Point location_in_screen(GetEventLocationInScreen(event));
drag_delegate_->dragged_window()->SetTransform(gfx::Transform());
if (event->type() == ui::ET_SCROLL_FLING_START &&
event->details().velocity_y() > kFlingToOverviewThreshold) {
DCHECK(Shell::Get()->window_selector_controller()->IsSelecting());
Shell::Get()->window_selector_controller()->window_selector()->AddItem(
drag_delegate_->dragged_window(), /*reposition=*/true,
/*animate=*/true);
}
drag_delegate_->EndWindowDrag(result, location_in_screen);
}
void TabletModeAppWindowDragController::UpdateDraggedWindow(
const gfx::Point& location_in_screen) {
DCHECK(drag_delegate_->dragged_window());
RootWindowController::ForWindow(drag_delegate_->dragged_window())
->GetShelfLayoutManager()
->UpdateVisibilityState();
float scale = CalculateWindowScale(location_in_screen.y());
gfx::Transform transform;
const gfx::Rect window_bounds = drag_delegate_->dragged_window()->bounds();
transform.Translate(
(location_in_screen.x() - window_bounds.x()) -
(initial_location_in_screen_.x() - window_bounds.x()) * scale,
(location_in_screen.y() - window_bounds.y()) -
(initial_location_in_screen_.y() - window_bounds.y()) * scale);
transform.Scale(scale, scale);
drag_delegate_->dragged_window()->SetTransform(transform);
}
float TabletModeAppWindowDragController::CalculateWindowScale(
int y_location_in_screen) const {
float minimum_scale =
static_cast<float>(new_selector_item_bounds_.height()) /
static_cast<float>(drag_delegate_->dragged_window()->bounds().height());
int y_full = new_selector_item_bounds_.y();
int y_diff = y_full - y_location_in_screen;
if (y_diff < 0)
return minimum_scale;
return (1.0f - minimum_scale) * y_diff / y_full + minimum_scale;
drag_delegate_->EndWindowDrag(result, GetEventLocationInScreen(event));
}
} // namespace ash
......@@ -38,25 +38,8 @@ class ASH_EXPORT TabletModeAppWindowDragController {
void EndWindowDrag(ui::GestureEvent* event,
wm::WmToplevelWindowEventHandler::DragResult result);
// Apply transform to the dragged window during dragging.
void UpdateDraggedWindow(const gfx::Point& location_in_screen);
// The scale of the window during drag is based on the distance from
// |y_location_in_screen| to the y position of |new_selector_item_bounds_|.
// The dragged window will become smaller when it becomes nearer to the new
// selector item. And then keep the minimum scale if it has been dragged
// further than the new selector item.
float CalculateWindowScale(int y_location_in_screen) const;
std::unique_ptr<TabletModeWindowDragDelegate> drag_delegate_;
gfx::Point initial_location_in_screen_;
// Overview mode will be triggered if a window is being dragged from the top
// of the display, and a new selector item will be created in the overview
// grid. See |new_selector_item_widget_| in WindowGrid for more info.
gfx::Rect new_selector_item_bounds_;
DISALLOW_COPY_AND_ASSIGN(TabletModeAppWindowDragController);
};
......
......@@ -6,6 +6,7 @@
#include "ash/shell.h"
#include "ash/wm/tablet_mode/tablet_mode_browser_window_drag_delegate.h"
#include "ash/wm/window_util.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/core/cursor_manager.h"
......@@ -40,23 +41,29 @@ TabletModeBrowserWindowDragController::
void TabletModeBrowserWindowDragController::Drag(
const gfx::Point& location_in_parent,
int event_flags) {
// Update dragged window's bounds.
gfx::Rect bounds = CalculateBoundsForDrag(location_in_parent);
if (bounds != GetTarget()->bounds()) {
gfx::Point location_in_screen = location_in_parent;
::wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen);
previous_location_in_screen_ = location_in_screen;
// Update the dragged window, the drag indicators, the preview window,
// source window position, blurred background, etc, if necessary.
if (wm::IsDraggingTabs(GetTarget())) {
// Update the dragged window's bounds if it's tab-dragging.
base::WeakPtr<TabletModeBrowserWindowDragController> resizer(
weak_ptr_factory_.GetWeakPtr());
GetTarget()->SetBounds(bounds);
drag_delegate_->ContinueWindowDrag(
location_in_screen,
TabletModeWindowDragDelegate::UpdateDraggedWindowType::UPDATE_BOUNDS,
CalculateBoundsForDrag(location_in_parent));
// Note, this might have been deleted when reaching here.
if (!resizer)
return;
} else {
// Otherwise, update the dragged window's transform.
drag_delegate_->ContinueWindowDrag(
location_in_screen, TabletModeWindowDragDelegate::
UpdateDraggedWindowType::UPDATE_TRANSFORM);
}
gfx::Point location_in_screen = location_in_parent;
::wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen);
previous_location_in_screen_ = location_in_screen;
// Update the drag indicators, snap preview window, source window position,
// blurred backgournd, etc, if necessary.
drag_delegate_->ContinueWindowDrag(location_in_screen);
}
void TabletModeBrowserWindowDragController::CompleteDrag() {
......
......@@ -4,6 +4,8 @@
#include "ash/wm/tablet_mode/tablet_mode_window_drag_delegate.h"
#include "ash/root_window_controller.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shell.h"
#include "ash/wm/overview/window_grid.h"
#include "ash/wm/overview/window_selector.h"
......@@ -34,12 +36,30 @@ WindowSelector* GetWindowSelector() {
: nullptr;
}
// Gets the new selector item's bounds in overview grid that is displaying in
// the same root window as |dragged_window|.
gfx::Rect GetNewSelectorItemBounds(aura::Window* dragged_window) {
if (!Shell::Get()->window_selector_controller()->IsSelecting())
return gfx::Rect();
WindowGrid* window_grid = GetWindowSelector()->GetGridWithRootWindow(
dragged_window->GetRootWindow());
if (!window_grid || window_grid->empty())
return gfx::Rect();
WindowSelectorItem* last_item = window_grid->window_list().back().get();
if (!window_grid->IsNewSelectorItemWindow(last_item->GetWindow()))
return gfx::Rect();
return last_item->target_bounds();
}
} // namespace
TabletModeWindowDragDelegate::TabletModeWindowDragDelegate()
: split_view_controller_(Shell::Get()->split_view_controller()),
split_view_drag_indicators_(std::make_unique<SplitViewDragIndicators>()) {
}
split_view_drag_indicators_(std::make_unique<SplitViewDragIndicators>()),
weak_ptr_factory_(this) {}
TabletModeWindowDragDelegate::~TabletModeWindowDragDelegate() = default;
......@@ -47,9 +67,15 @@ void TabletModeWindowDragDelegate::StartWindowDrag(
aura::Window* dragged_window,
const gfx::Point& location_in_screen) {
dragged_window_ = dragged_window;
initial_location_in_screen_ = location_in_screen;
PrepareForDraggedWindow(location_in_screen);
// Update the shelf's visibility.
RootWindowController::ForWindow(dragged_window_)
->GetShelfLayoutManager()
->UpdateVisibilityState();
// Disable the backdrop on the dragged window.
original_backdrop_mode_ = dragged_window_->GetProperty(kBackdropWindowMode);
dragged_window_->SetProperty(kBackdropWindowMode,
......@@ -72,10 +98,32 @@ void TabletModeWindowDragDelegate::StartWindowDrag(
GetWindowSelector()->OnWindowDragStarted(dragged_window_,
/*animate=*/was_overview_open);
}
new_selector_item_bounds_ = GetNewSelectorItemBounds(dragged_window_);
}
void TabletModeWindowDragDelegate::ContinueWindowDrag(
const gfx::Point& location_in_screen) {
const gfx::Point& location_in_screen,
UpdateDraggedWindowType type,
const gfx::Rect& target_bounds) {
if (type == UpdateDraggedWindowType::UPDATE_BOUNDS) {
// UPDATE_BOUNDS is used when dragging tab(s) out of a browser window.
// Changing bounds might delete ourselves as the dragged (browser) window
// tab(s) might merge into another browser window.
base::WeakPtr<TabletModeWindowDragDelegate> delegate(
weak_ptr_factory_.GetWeakPtr());
if (target_bounds != dragged_window_->bounds()) {
dragged_window_->SetBounds(target_bounds);
if (!delegate)
return;
}
} else { // type == UpdateDraggedWindowType::UPDATE_TRANSFORM
// UPDATE_TRANSFORM is used when dragging an entire window around, either
// it's a browser window or an app window.
UpdateDraggedWindowTransform(location_in_screen);
}
// For child classes to do their special handling if any.
UpdateForDraggedWindow(location_in_screen);
// Update drag indicators and preview window if necessary.
......@@ -109,6 +157,15 @@ void TabletModeWindowDragDelegate::EndWindowDrag(
location_in_screen);
split_view_drag_indicators_->SetIndicatorState(IndicatorState::kNone,
location_in_screen);
// If |dragged_window_|'s transform has changed during dragging, and it has
// not been added into overview grid, restore its transform to identity.
if (!dragged_window_->layer()->GetTargetTransform().IsIdentity() &&
(!GetWindowSelector() ||
!GetWindowSelector()->IsWindowInOverview(dragged_window_))) {
dragged_window_->SetTransform(gfx::Transform());
}
dragged_window_ = nullptr;
}
......@@ -228,4 +285,31 @@ IndicatorState TabletModeWindowDragDelegate::GetIndicatorState(
return can_snap ? IndicatorState::kDragArea : IndicatorState::kCannotSnap;
}
void TabletModeWindowDragDelegate::UpdateDraggedWindowTransform(
const gfx::Point& location_in_screen) {
DCHECK(Shell::Get()->window_selector_controller()->IsSelecting());
// Calculate the desired scale along the y-axis. The scale of the window
// during drag is based on the distance from |y_location_in_screen| to the y
// position of |new_selector_item_bounds_|. The dragged window will become
// smaller when it becomes nearer to the new selector item. And then keep the
// minimum scale if it has been dragged further than the new selector item.
float scale = static_cast<float>(new_selector_item_bounds_.height()) /
static_cast<float>(dragged_window_->bounds().height());
int y_full = new_selector_item_bounds_.y();
int y_diff = y_full - location_in_screen.y();
if (y_diff >= 0)
scale = (1.0f - scale) * y_diff / y_full + scale;
gfx::Transform transform;
const gfx::Rect window_bounds = dragged_window_->bounds();
transform.Translate(
(location_in_screen.x() - window_bounds.x()) -
(initial_location_in_screen_.x() - window_bounds.x()) * scale,
(location_in_screen.y() - window_bounds.y()) -
(initial_location_in_screen_.y() - window_bounds.y()) * scale);
transform.Scale(scale, scale);
dragged_window_->SetTransform(transform);
}
} // namespace ash
......@@ -10,6 +10,7 @@
#include "ash/public/cpp/window_properties.h"
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/wm_toplevel_window_event_handler.h"
#include "base/memory/weak_ptr.h"
namespace ash {
......@@ -17,19 +18,34 @@ enum class IndicatorState;
class SplitViewDragIndicators;
// This class includes the common logic when dragging a window around, either
// it's a browser window, or an app window. It does everything needs to be done
// other than updating the dragged window (which is done by DragController),
// e.g., it decides when/where to show the drag indicators and preview windows,
// shows/hides the backdrop, interacts with overview and splitview, etc.
// it's a browser window, or an app window. It does almost everything needs to
// be done, including updating the dragged window's bounds (if it's dragged by
// tabs) or transform (if it's dragged by entire window). it also decides
// when/where to show the drag indicators and preview windows, shows/hides the
// backdrop, interacts with overview and splitview, etc.
class TabletModeWindowDragDelegate {
public:
enum class UpdateDraggedWindowType {
UPDATE_BOUNDS,
UPDATE_TRANSFORM,
};
TabletModeWindowDragDelegate();
virtual ~TabletModeWindowDragDelegate();
// Called when a window starts/continues/ends being dragged around.
// Called when a window starts being dragged.
void StartWindowDrag(aura::Window* window,
const gfx::Point& location_in_screen);
void ContinueWindowDrag(const gfx::Point& location_in_screen);
// Called when a window continues being dragged. |type| specifies how we want
// to update the dragged window during dragging, and |target_bounds| is the
// target window bounds for the dragged window if |type| is UPDATE_BOUNDS.
// Note |target_bounds| has no use if |type| is UPDATE_TRANSFROM.
void ContinueWindowDrag(const gfx::Point& location_in_screen,
UpdateDraggedWindowType type,
const gfx::Rect& target_bounds = gfx::Rect());
// Calls when a window ends dragging with its drag result |result|.
void EndWindowDrag(wm::WmToplevelWindowEventHandler::DragResult result,
const gfx::Point& location_in_screen);
......@@ -68,6 +84,9 @@ class TabletModeWindowDragDelegate {
// Returns the IndicatorState according to |location_in_screen|.
IndicatorState GetIndicatorState(const gfx::Point& location_in_screen) const;
// Update the dragged window's transform during dragging.
void UpdateDraggedWindowTransform(const gfx::Point& location_in_screen);
SplitViewController* const split_view_controller_;
// A widget to display the drag indicators and preview window.
......@@ -78,6 +97,16 @@ class TabletModeWindowDragDelegate {
// The backdrop should be disabled during dragging and resumed after dragging.
BackdropWindowMode original_backdrop_mode_ = BackdropWindowMode::kAuto;
gfx::Point initial_location_in_screen_;
// Overview mode will be triggered if a window is being dragged, and a new
// selector item will be created in the overview grid. The variable stores
// the new selector item bounds in overview and will be used to calculate
// the desired window tranform during dragging.
gfx::Rect new_selector_item_bounds_;
base::WeakPtrFactory<TabletModeWindowDragDelegate> weak_ptr_factory_;
private:
DISALLOW_COPY_AND_ASSIGN(TabletModeWindowDragDelegate);
};
......
......@@ -1790,22 +1790,6 @@ TEST_F(TabletModeWindowManagerTest, SetPropertyOnUnmanagedWindow) {
window->Show();
}
// Test that there is no window resizer in tablet mode.
TEST_F(TabletModeWindowManagerTest, NoWindowResizerInTabletMode) {
gfx::Rect rect(10, 10, 200, 200);
std::unique_ptr<aura::Window> window(
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
std::unique_ptr<WindowResizer> resizer(CreateWindowResizer(
window.get(), gfx::Point(), HTCAPTION, ::wm::WINDOW_MOVE_SOURCE_MOUSE));
EXPECT_TRUE(resizer.get());
resizer.reset();
CreateTabletModeWindowManager();
resizer = CreateWindowResizer(window.get(), gfx::Point(), HTCAPTION,
::wm::WINDOW_MOVE_SOURCE_MOUSE);
EXPECT_FALSE(resizer.get());
}
// Test that the minimized window bounds doesn't change until it's unminimized.
TEST_F(TabletModeWindowManagerTest, DontChangeBoundsForMinimizedWindow) {
gfx::Rect rect(10, 10, 200, 50);
......
......@@ -21,7 +21,6 @@
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_positioning_utils.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "ash/wm/wm_event.h"
#include "ash/wm/workspace/phantom_window_controller.h"
#include "ash/wm/workspace/two_step_edge_cycler.h"
......@@ -69,8 +68,8 @@ std::unique_ptr<WindowResizer> CreateWindowResizer(
->tablet_mode_controller()
->IsTabletModeWindowManagerEnabled()) {
// We still don't allow any dragging or resizing happening on the area other
// then caption area. Only allow dragging that happends on the tab(s).
if (window_component != HTCAPTION || !wm::IsDraggingTabs(window))
// then caption area.
if (window_component != HTCAPTION)
return nullptr;
window_state->CreateDragDetails(point_in_parent, window_component, source);
......
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