Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(527)

Unified Diff: ui/views/cocoa/bridged_native_widget.mm

Issue 1747803003: MacViews: Implement Tab Dragging (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Extract CocoaWindowMoveLoop, fix review issues. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/views/cocoa/bridged_native_widget.mm
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm
index 6f5dec0f96864ede56c8a7cf940de5ebf964aa92..2ef4548ff7bbbf904b18d574a90d448a28c395ca 100644
--- a/ui/views/cocoa/bridged_native_widget.mm
+++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -35,16 +35,6 @@
#include "ui/views/widget/widget_aura_utils.h"
#include "ui/views/widget/widget_delegate.h"
-extern "C" {
-
-typedef int32_t CGSConnection;
-CGSConnection _CGSDefaultConnection();
-CGError CGSSetWindowBackgroundBlurRadius(CGSConnection connection,
- NSInteger windowNumber,
- int radius);
-
-}
-
// The NSView that hosts the composited CALayer drawing the UI. It fills the
// window but is not hittable so that accessibility hit tests always go to the
// BridgedContentView.
@@ -94,6 +84,8 @@ const int kResizeAreaCornerSize = 12;
int kWindowPropertiesKey;
+bool g_ignore_next_mouse_down_for_draggable_regions = false;
+
float GetDeviceScaleFactorFromView(NSView* view) {
gfx::Display display =
gfx::Screen::GetScreen()->GetDisplayNearestWindow(view);
@@ -191,6 +183,11 @@ NSEvent* RepostEventIfHandledByWindow(NSEvent* ns_event) {
// - any repost loop.
if (repost_state == NONE) {
+ if (g_ignore_next_mouse_down_for_draggable_regions) {
+ g_ignore_next_mouse_down_for_draggable_regions = false;
+ return ns_event;
+ }
+
if (WindowWantsMouseDownReposted(ns_event)) {
repost_state = EXPECTING_REPOST;
reposted_event_number = event_number;
@@ -265,6 +262,16 @@ scoped_refptr<base::SingleThreadTaskRunner> GetCompositorTaskRunner() {
} // namespace
+extern "C" {
+
+typedef int32_t CGSConnection;
+CGSConnection _CGSDefaultConnection();
+CGError CGSSetWindowBackgroundBlurRadius(CGSConnection connection,
+ NSInteger windowNumber,
+ int radius);
+
+}
+
namespace views {
// static
@@ -569,6 +576,53 @@ bool BridgedNativeWidget::HasCapture() {
return mouse_capture_ && mouse_capture_->IsActive();
}
+Widget::MoveLoopResult BridgedNativeWidget::RunMoveLoop(
+ const gfx::Vector2d& drag_offset) {
+ DCHECK(!HasCapture());
+ DCHECK(!window_move_loop_);
+
+ // First, position the window in the right place. The point |drag_offset|
+ // away from the top-left corner needs to be positioned under the mouse.
+ // TODO(tapted): Figure out why the toolkit-views drag controller doesn't get
+ // this right when it first initializes the Widget.
+ NSPoint mouse_in_screen = gfx::ScreenPointToNSPoint(
+ gfx::Screen::GetScreen()->GetCursorScreenPoint());
+ NSRect frame = [window_ frame];
+ frame.origin.x = mouse_in_screen.x - drag_offset.x();
+ frame.origin.y = mouse_in_screen.y - NSHeight(frame) + drag_offset.y();
+
+ // After setting the frame to correct the initial offset, the drag controller
+ // may immediately want to quit when it's notified of the new bounds. So the
+ // MoveLoop must be set up before the call to setFrame.
+ window_move_loop_.reset(new CocoaWindowMoveLoop(this));
+
+ // Animating may provide a less janky UX, but something custom would be
+ // required so that it follows updates to the mouse position.
+ [window_ setFrame:frame display:YES animate:NO];
+
+ // Setting the frame will call OnWidgetBoundsChanged(), which could result in
+ // a call to EndMoveLoop().
+ if (!window_move_loop_)
+ return Widget::MOVE_LOOP_SUCCESSFUL;
+
+ return window_move_loop_->Run();
+
+ // |this| may be destroyed during the RunLoop, causing it to exit early.
+ // Even if that doesn't happen, CocoaWindowMoveLoop will clean itself up by
+ // calling EndMoveLoop(). So window_move_loop_ will always be null before the
+ // function returns. But don't DCHECK since |this| might not be valid.
+}
+
+void BridgedNativeWidget::EndMoveLoop() {
+ DCHECK(window_move_loop_);
+ window_move_loop_->End();
+ window_move_loop_.reset();
+}
+
+bool BridgedNativeWidget::IsRunMoveLoopActive() const {
+ return window_move_loop_.get();
tapted 2016/03/11 09:38:28 is the .get() needed?
themblsha 2016/04/05 17:20:42 Yes. error: no viable conversion from returned val
+}
+
void BridgedNativeWidget::SetNativeWindowProperty(const char* name,
void* value) {
NSString* key = [NSString stringWithUTF8String:name];
@@ -590,6 +644,7 @@ void BridgedNativeWidget::SetCursor(NSCursor* cursor) {
}
void BridgedNativeWidget::OnWindowWillClose() {
+ DCHECK(!drag_run_loop_);
if (parent_) {
parent_->RemoveChildWindow(this);
parent_ = nullptr;
@@ -692,6 +747,10 @@ void BridgedNativeWidget::OnSizeChanged() {
[bridged_view_ updateWindowMask];
}
+void BridgedNativeWidget::OnPositionChanged() {
+ native_widget_mac_->GetWidget()->OnNativeWidgetMove();
+}
+
void BridgedNativeWidget::OnVisibilityChanged() {
OnVisibilityChangedTo([window_ isVisible]);
}
@@ -1244,4 +1303,9 @@ void BridgedNativeWidget::SetDraggable(bool draggable) {
[window_ setMovableByWindowBackground:YES];
}
+// static
+void BridgedNativeWidget::IgnoreNextMouseDownForDraggableRegions() {
+ g_ignore_next_mouse_down_for_draggable_regions = true;
+}
+
} // namespace views

Powered by Google App Engine
This is Rietveld 408576698