web_contents_view_mac.mm revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Copyright (c) 2012 The Chromium Authors. All rights reserved.
243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Use of this source code is governed by a BSD-style license that can be
343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// found in the LICENSE file.
443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#import <Carbon/Carbon.h>
643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#import "content/browser/web_contents/web_contents_view_mac.h"
843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include <string>
1043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#import "base/mac/scoped_sending_event.h"
1243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "base/message_loop/message_loop.h"
1343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#import "base/message_loop/message_pump_mac.h"
1443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "content/browser/renderer_host/popup_menu_helper_mac.h"
1543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "content/browser/renderer_host/render_view_host_factory.h"
1643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "content/browser/renderer_host/render_view_host_impl.h"
172e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis#include "content/browser/renderer_host/render_widget_host_view_mac.h"
1843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "content/browser/web_contents/web_contents_impl.h"
199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#import "content/browser/web_contents/web_drag_dest_mac.h"
20769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#import "content/browser/web_contents/web_drag_source_mac.h"
2135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek#include "content/common/view_messages.h"
22ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks#include "content/public/browser/web_contents_delegate.h"
239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "content/public/browser/web_contents_view_delegate.h"
2443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "skia/ext/skia_utils_mac.h"
2543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#import "third_party/mozilla/NSPasteboard+Utils.h"
269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "ui/base/clipboard/custom_data_helper.h"
27769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#import "ui/base/cocoa/focus_tracker.h"
28e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis#include "ui/base/dragdrop/cocoa_dnd_util.h"
2943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "ui/gfx/image/image_skia_util_mac.h"
3043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
31ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenekusing blink::WebDragOperation;
3243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisusing blink::WebDragOperationsMask;
339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisusing content::DropData;
349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisusing content::PopupMenuHelper;
35769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisusing content::RenderViewHostFactory;
36769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisusing content::RenderWidgetHostView;
37769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisusing content::RenderWidgetHostViewMac;
38e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisusing content::WebContents;
39769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisusing content::WebContentsImpl;
4030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisusing content::WebContentsViewMac;
4118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek
42cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks// Ensure that the blink::WebDragOperation enum values stay in sync with
43af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks// NSDragOperation constants, since the code below static_casts between 'em.
44183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis#define COMPILE_ASSERT_MATCHING_ENUM(name) \
45183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  COMPILE_ASSERT(int(NS##name) == int(blink::Web##name), enum_mismatch_##name)
46769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCOMPILE_ASSERT_MATCHING_ENUM(DragOperationNone);
47e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios KyrtzidisCOMPILE_ASSERT_MATCHING_ENUM(DragOperationCopy);
48e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios KyrtzidisCOMPILE_ASSERT_MATCHING_ENUM(DragOperationLink);
49e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios KyrtzidisCOMPILE_ASSERT_MATCHING_ENUM(DragOperationGeneric);
50e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios KyrtzidisCOMPILE_ASSERT_MATCHING_ENUM(DragOperationPrivate);
51e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios KyrtzidisCOMPILE_ASSERT_MATCHING_ENUM(DragOperationMove);
52e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios KyrtzidisCOMPILE_ASSERT_MATCHING_ENUM(DragOperationDelete);
534d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios KyrtzidisCOMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery);
544d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
5566c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks@interface WebContentsViewCocoa (Private)
5666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks- (id)initWithWebContentsViewMac:(WebContentsViewMac*)w;
5766c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks- (void)registerDragTypes;
5866c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks- (void)setCurrentDragOperation:(NSDragOperation)operation;
5966c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks- (DropData*)dropData;
6066c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks- (void)startDragWithDropData:(const DropData&)dropData
6166c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks            dragOperationMask:(NSDragOperation)operationMask
6266c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                        image:(NSImage*)image
6366c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                       offset:(NSPoint)offset;
6466c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks- (void)cancelDeferredClose;
6566c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks- (void)clearWebContentsView;
6666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks- (void)closeTabAfterEvent;
6766c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks- (void)viewDidBecomeFirstResponder:(NSNotification*)notification;
6835bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek@end
6935bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek
7035bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremeneknamespace content {
7135bdbf40624beba3fc00cb72ab444659939c1a6bTed KremenekWebContentsViewPort* CreateWebContentsView(
7235bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek    WebContentsImpl* web_contents,
73ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    WebContentsViewDelegate* delegate,
74ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    RenderViewHostDelegateView** render_view_host_delegate_view) {
7535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  WebContentsViewMac* rv = new WebContentsViewMac(web_contents, delegate);
7635bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  *render_view_host_delegate_view = rv;
7735bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  return rv;
7835bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek}
7935bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek
804d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios KyrtzidisWebContentsViewMac::WebContentsViewMac(WebContentsImpl* web_contents,
814d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis                                       WebContentsViewDelegate* delegate)
824d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis    : web_contents_(web_contents),
83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      delegate_(delegate),
84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      allow_overlapping_views_(false),
85ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek      overlay_view_(NULL),
86ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek      underlay_view_(NULL) {
874d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis}
88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisWebContentsViewMac::~WebContentsViewMac() {
904d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  // This handles the case where a renderer close call was deferred
914d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  // while the user was operating a UI control which resulted in a
924d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  // close.  In that case, the Cocoa view outlives the
93769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // WebContentsViewMac instance due to Cocoa retain count.
94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  [cocoa_view_ cancelDeferredClose];
95ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  [cocoa_view_ clearWebContentsView];
96ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek}
974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisgfx::NativeView WebContentsViewMac::GetNativeView() const {
99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  return cocoa_view_.get();
1004d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis}
1014d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
1024d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisgfx::NativeView WebContentsViewMac::GetContentNativeView() const {
103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (!rwhv)
105ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    return NULL;
106ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  return rwhv->GetNativeView();
1074d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis}
108769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisgfx::NativeWindow WebContentsViewMac::GetTopLevelNativeWindow() const {
1104d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  return [cocoa_view_.get() window];
1114d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis}
1124d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid WebContentsViewMac::GetContainerBounds(gfx::Rect* out) const {
114769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // Convert bounds to window coordinate space.
115ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  NSRect bounds =
116ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek      [cocoa_view_.get() convertRect:[cocoa_view_.get() bounds] toView:nil];
1174d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
118769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // Convert bounds to screen coordinate space.
11943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  NSWindow* window = [cocoa_view_.get() window];
12043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  bounds.origin = [window convertBaseToScreen:bounds.origin];
1212e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
1222e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  // Flip y to account for screen flip.
12343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
1242e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  bounds.origin.y = [screen frame].size.height - bounds.origin.y
1259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      - bounds.size.height;
1269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  *out = gfx::Rect(NSRectToCGRect(bounds));
127d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis}
128d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis
129deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisvoid WebContentsViewMac::StartDragging(
130deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    const DropData& drop_data,
1314e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    WebDragOperationsMask allowed_operations,
1322e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis    const gfx::ImageSkia& image,
133ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    const gfx::Vector2d& image_offset,
134ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek    const DragEventSourceInfo& event_info) {
1354d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  // By allowing nested tasks, the code below also allows Close(),
1369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // which would deallocate |this|.  The same problem can occur while
1379fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // processing -sendEvent:, so Close() is deferred in that case.
1389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // Drags from web content do not come via -sendEvent:, this sets the
1399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // same flag -sendEvent: would.
1409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  base::mac::ScopedSendingEvent sending_event_scoper;
1419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1423fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  // The drag invokes a nested event loop, arrange to continue
1433fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  // processing events.
1449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  base::MessageLoop::ScopedNestableTaskAllower allow(
1453fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis      base::MessageLoop::current());
146deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  NSDragOperation mask = static_cast<NSDragOperation>(allowed_operations);
1473fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  NSPoint offset = NSPointFromCGPoint(
1483fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis      gfx::PointAtOffsetFromOrigin(image_offset).ToCGPoint());
1493fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  [cocoa_view_ startDragWithDropData:drop_data
1503fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis                   dragOperationMask:mask
1519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                               image:gfx::NSImageFromImageSkia(image)
152769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              offset:offset];
1539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
1543fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
1553fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidisvoid WebContentsViewMac::OnTabCrashed(base::TerminationStatus /* status */,
1569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                                      int /* error_code */) {
15743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis}
1589fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid WebContentsViewMac::SizeContents(const gfx::Size& size) {
1609fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // TODO(brettw | japhet) This is a hack and should be removed.
1619fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // See web_contents_view.h.
1629fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // Note(erikchen): This method has /never/ worked correctly. I've removed the
1639fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // previous implementation.
1649fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
1659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid WebContentsViewMac::Focus() {
1679fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  NSWindow* window = [cocoa_view_.get() window];
1689fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  [window makeFirstResponder:GetContentNativeView()];
1699fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  if (![window isVisible])
1709fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    return;
171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  [window makeKeyAndOrderFront:nil];
172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid WebContentsViewMac::SetInitialFocus() {
175c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  if (web_contents_->FocusLocationBarByDefault())
176c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks    web_contents_->SetFocusToLocationBar(false);
177c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  else
178c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks    [[cocoa_view_.get() window] makeFirstResponder:GetContentNativeView()];
179c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks}
180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
181cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidisvoid WebContentsViewMac::StoreFocus() {
182769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // We're explicitly being asked to store focus, so don't worry if there's
183769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // already a view saved.
184769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  focus_tracker_.reset(
185769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      [[FocusTracker alloc] initWithWindow:[cocoa_view_ window]]);
186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
188c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaksvoid WebContentsViewMac::RestoreFocus() {
189c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  // TODO(avi): Could we be restoring a view that's no longer in the key view
190c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  // chain?
191c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  if (!(focus_tracker_.get() &&
192c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks        [focus_tracker_ restoreFocusInWindow:[cocoa_view_ window]])) {
193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    // Fall back to the default focus behavior if we could not restore focus.
194cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis    // TODO(shess): If location-bar gets focus by default, this will
195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    // select-all in the field.  If there was a specific selection in
196514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek    // the field when we navigated away from it, we should restore
197514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek    // that selection.
198514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek    SetInitialFocus();
199769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
200769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  focus_tracker_.reset(nil);
202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
203cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis
204514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed KremenekDropData* WebContentsViewMac::GetDropData() const {
205514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek  return [cocoa_view_ dropData];
206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
207769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
208769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid WebContentsViewMac::UpdateDragCursor(WebDragOperation operation) {
209cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis  [cocoa_view_ setCurrentDragOperation: operation];
210769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
211769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
212769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid WebContentsViewMac::GotFocus() {
213769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // This is only used in the views FocusManager stuff but it bleeds through
214769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // all subclasses. http://crbug.com/21875
215769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
216769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
217cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis// This is called when the renderer asks us to take focus back (i.e., it has
218769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// iterated past the last focusable element on the page).
219769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid WebContentsViewMac::TakeFocus(bool reverse) {
220769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (reverse) {
221769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    [[cocoa_view_ window] selectPreviousKeyView:cocoa_view_.get()];
222769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  } else {
223769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    [[cocoa_view_ window] selectNextKeyView:cocoa_view_.get()];
224769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
225cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis}
226cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis
227769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid WebContentsViewMac::ShowContextMenu(
228769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    content::RenderFrameHost* render_frame_host,
229769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const ContextMenuParams& params) {
230769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // Allow delegates to handle the context menu operation first.
231cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis  if (web_contents_->GetDelegate() &&
232bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek      web_contents_->GetDelegate()->HandleContextMenu(params)) {
233bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek    return;
234bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  }
235bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek
236769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (delegate())
237769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    delegate()->ShowContextMenu(render_frame_host, params);
238312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  else
239312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    DLOG(ERROR) << "Cannot show context menus without a delegate.";
240312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis}
241312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
242ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks// Display a popup menu for WebKit using Cocoa widgets.
243ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaksvoid WebContentsViewMac::ShowPopupMenu(
244312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    const gfx::Rect& bounds,
24530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    int item_height,
24630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    double item_font_size,
24730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    int selected_item,
24830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    const std::vector<MenuItem>& items,
249af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis    bool right_aligned,
250af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks    bool allow_multiple_selection) {
251af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  popup_menu_helper_.reset(
252af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks      new PopupMenuHelper(web_contents_->GetRenderViewHost()));
253af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  popup_menu_helper_->ShowPopupMenu(bounds, item_height, item_font_size,
254cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                                    selected_item, items, right_aligned,
255cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                                    allow_multiple_selection);
256f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  popup_menu_helper_.reset();
2574e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks}
258cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
259183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid WebContentsViewMac::HidePopupMenu() {
260c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  if (popup_menu_helper_)
261c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks    popup_menu_helper_->Hide();
262c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks}
263c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks
26423111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenekgfx::Rect WebContentsViewMac::GetViewBounds() const {
265183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  // This method is not currently used on mac.
266183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  NOTIMPLEMENTED();
267183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  return gfx::Rect();
268c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks}
269c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks
270c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaksvoid WebContentsViewMac::SetAllowOverlappingViews(bool overlapping) {
271c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  if (allow_overlapping_views_ == overlapping)
272183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    return;
273183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
274183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  allow_overlapping_views_ = overlapping;
2750b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks  RenderWidgetHostViewMac* view = static_cast<RenderWidgetHostViewMac*>(
2760b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      web_contents_->GetRenderWidgetHostView());
277183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  if (view)
278183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    view->SetAllowOverlappingViews(allow_overlapping_views_);
27923111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek}
280183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
281183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisbool WebContentsViewMac::GetAllowOverlappingViews() const {
282537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  return allow_overlapping_views_;
283537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose}
284537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose
285537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rosevoid WebContentsViewMac::SetOverlayView(
286537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose    WebContentsView* overlay, const gfx::Point& offset) {
287537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  DCHECK(!underlay_view_);
288537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  if (overlay_view_)
289537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose    RemoveOverlayView();
29066c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks
29166c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  overlay_view_ = static_cast<WebContentsViewMac*>(overlay);
29223111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  DCHECK(!overlay_view_->overlay_view_);
29323111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  overlay_view_->underlay_view_ = this;
29435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  overlay_view_offset_ = offset;
295537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  UpdateRenderWidgetHostViewOverlay();
29666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks}
29766c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks
298183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid WebContentsViewMac::RemoveOverlayView() {
299312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  DCHECK(overlay_view_);
30023111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek
30123111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  RenderWidgetHostViewMac* rwhv = static_cast<RenderWidgetHostViewMac*>(
302312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis      web_contents_->GetRenderWidgetHostView());
303e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  if (rwhv)
304e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    rwhv->RemoveOverlayView();
305e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
306e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  overlay_view_->underlay_view_ = NULL;
307e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  overlay_view_ = NULL;
3089be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek}
3099be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
3109c378f705405d37f49795d5e915989de774fe11fTed Kremenekvoid WebContentsViewMac::UpdateRenderWidgetHostViewOverlay() {
3119be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  RenderWidgetHostViewMac* rwhv = static_cast<RenderWidgetHostViewMac*>(
3129be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek      web_contents_->GetRenderWidgetHostView());
313e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  if (!rwhv)
314dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose    return;
315dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose
316dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  if (overlay_view_) {
317dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose    RenderWidgetHostViewMac* overlay_rwhv =
318dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose        static_cast<RenderWidgetHostViewMac*>(
319dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose            overlay_view_->web_contents_->GetRenderWidgetHostView());
320dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose    if (overlay_rwhv)
321dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose      rwhv->SetOverlayView(overlay_rwhv, overlay_view_offset_);
32223111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  }
323dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose
324dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  if (underlay_view_) {
325769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    RenderWidgetHostViewMac* underlay_rwhv =
326769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        static_cast<RenderWidgetHostViewMac*>(
3279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis            underlay_view_->web_contents_->GetRenderWidgetHostView());
3289fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    if (underlay_rwhv)
3299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      underlay_rwhv->SetOverlayView(rwhv, underlay_view_->overlay_view_offset_);
3309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
3319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
3324d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
333769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid WebContentsViewMac::CreateView(
334769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const gfx::Size& initial_size, gfx::NativeView context) {
3359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  WebContentsViewCocoa* view =
336769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      [[WebContentsViewCocoa alloc] initWithWebContentsViewMac:this];
3379fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  cocoa_view_.reset(view);
338769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
339769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
340769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisRenderWidgetHostView* WebContentsViewMac::CreateViewForWidget(
341769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    RenderWidgetHost* render_widget_host) {
342769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (render_widget_host->GetView()) {
343769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    // During testing, the view will already be set up in most cases to the
3444d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis    // test view, so we don't want to clobber it with a real one. To verify that
3454d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis    // this actually is happening (and somebody isn't accidentally creating the
3464d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis    // view twice), we check for the RVH Factory, which will be set when we're
3474d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis    // making special ones (which go along with the special views).
3484d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis    DCHECK(RenderViewHostFactory::has_factory());
349bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek    return render_widget_host->GetView();
350bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  }
351390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks
352769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  RenderWidgetHostViewMac* view = static_cast<RenderWidgetHostViewMac*>(
3534d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      RenderWidgetHostView::CreateViewForWidget(render_widget_host));
354390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks  if (delegate()) {
355390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks    base::scoped_nsobject<NSObject<RenderWidgetHostViewMacDelegate> >
356390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks        rw_delegate(
3574d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis            delegate()->CreateRenderWidgetHostViewDelegate(render_widget_host));
3584d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
35930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    view->SetDelegate(rw_delegate.get());
3604d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  }
361af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  view->SetAllowOverlappingViews(allow_overlapping_views_);
3624d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3634d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  // Fancy layout comes later; for now just make it our size and resize it
364f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  // with us. In case there are other siblings of the content area, we want
365cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  // to make sure the content area is on the bottom so other things draw over
3664d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  // it.
3674d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  NSView* view_view = view->GetNativeView();
3684d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  [view_view setFrame:[cocoa_view_.get() bounds]];
3694d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  [view_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
37023111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  // Add the new view below all other views; this also keeps it below any
3714d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  // overlay view installed.
37223111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  [cocoa_view_.get() addSubview:view_view
37335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                     positioned:NSWindowBelow
37466c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                     relativeTo:nil];
37566c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  // For some reason known only to Cocoa, the autorecalculation of the key view
37666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  // loop set on the window doesn't set the next key view when the subview is
3774d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  // added. On 10.6 things magically work fine; on 10.5 they fail
3784d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  // <http://crbug.com/61493>. Digging into Cocoa key view loop code yielded
37923111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  // madness; TODO(avi,rohit): look at this again and figure out what's really
3804d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  // going on.
38123111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  [cocoa_view_.get() setNextKeyView:view_view];
38218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  return view;
3834d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis}
3844d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3854d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios KyrtzidisRenderWidgetHostView* WebContentsViewMac::CreateViewForPopupWidget(
3864d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis    RenderWidgetHost* render_widget_host) {
387769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
388dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks}
389dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks
390dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaksvoid WebContentsViewMac::SetPageTitle(const base::string16& title) {
391dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks  // Meaningless on the Mac; widgets don't have a "title" attribute
392dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks}
3939be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
3949be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
3959be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekvoid WebContentsViewMac::RenderViewCreated(RenderViewHost* host) {
3969be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  // We want updates whenever the intrinsic width of the webpage changes.
397769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // Put the RenderView into that mode. The preferred width is used for example
398769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // when the "zoom" button in the browser window is clicked.
399769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  host->EnablePreferredSizeMode();
400769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
401769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
402769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid WebContentsViewMac::RenderViewSwappedIn(RenderViewHost* host) {
403769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  UpdateRenderWidgetHostViewOverlay();
404769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
405769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
406769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid WebContentsViewMac::SetOverscrollControllerEnabled(bool enabled) {
407769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
408312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
409312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisbool WebContentsViewMac::IsEventTracking() const {
41030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  return base::MessagePumpMac::IsHandlingSendEvent();
41130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis}
412af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
413af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis// Arrange to call CloseTab() after we're back to the main event loop.
414cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis// The obvious way to do this would be PostNonNestableTask(), but that
415cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis// will fire when the event-tracking loop polls for events.  So we
416183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis// need to bounce the message via Cocoa, instead.
417183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid WebContentsViewMac::CloseTabAfterEventTracking() {
418183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  [cocoa_view_ cancelDeferredClose];
419183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  [cocoa_view_ performSelector:@selector(closeTabAfterEvent)
420183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                    withObject:nil
421183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                    afterDelay:0.0];
422183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
423312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
424312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid WebContentsViewMac::CloseTab() {
425e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  web_contents_->Close(web_contents_->GetRenderViewHost());
426e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis}
427dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks
428dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks}  // namespace content
4299be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
4309be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek@implementation WebContentsViewCocoa
431769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
432deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis- (id)initWithWebContentsViewMac:(WebContentsViewMac*)w {
433deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  self = [super initWithFrame:NSZeroRect];
434deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  if (self != nil) {
435deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    webContentsView_ = w;
4364d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis    dragDest_.reset(
437deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis        [[WebDragDest alloc] initWithWebContentsImpl:[self webContents]]);
438deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    [self registerDragTypes];
439deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
440deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    [[NSNotificationCenter defaultCenter]
441deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis         addObserver:self
442deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis            selector:@selector(viewDidBecomeFirstResponder:)
443deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis                name:kViewDidBecomeFirstResponder
444deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis              object:nil];
445deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
446deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    if (webContentsView_->delegate()) {
447deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      [dragDest_ setDragDelegate:webContentsView_->delegate()->
448deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis          GetDragDestDelegate()];
449deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    }
450deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
451deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  return self;
452deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis}
453deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
454deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis- (void)dealloc {
455deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  // Cancel any deferred tab closes, just in case.
456deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  [self cancelDeferredClose];
457deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
458deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  // This probably isn't strictly necessary, but can't hurt.
459deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  [self unregisterDraggedTypes];
460deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
461769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  [[NSNotificationCenter defaultCenter] removeObserver:self];
462769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
46343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  [super dealloc];
46443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis}
4659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
4669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// Registers for the view for the appropriate drag types.
4679fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis- (void)registerDragTypes {
468deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  NSArray* types = [NSArray arrayWithObjects:
469deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      ui::kChromeDragDummyPboardType,
4703fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis      kWebURLsWithTitlesPboardType,
4713fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis      NSURLPboardType,
4723fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis      NSStringPboardType,
473769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      NSHTMLPboardType,
474769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      NSRTFPboardType,
4759fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      NSFilenamesPboardType,
4769fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      ui::kWebCustomDataPboardType,
4779fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      nil];
4789fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  [self registerForDraggedTypes:types];
4799fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
4809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
481769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (void)setCurrentDragOperation:(NSDragOperation)operation {
4829fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  [dragDest_ setCurrentOperation:operation];
483686775deca8b8685eb90801495880e3abdd844c2Chris Lattner}
4849fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
4859fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis- (DropData*)dropData {
486769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  return [dragDest_ currentDropData];
487769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
488769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
489769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (WebContentsImpl*)webContents {
490769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (webContentsView_ == NULL)
491769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    return NULL;
492769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  return webContentsView_->web_contents();
493769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
494769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
495769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (void)mouseEvent:(NSEvent*)theEvent {
496769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  WebContentsImpl* webContents = [self webContents];
497769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (webContents && webContents->GetDelegate()) {
498769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    NSPoint location = [NSEvent mouseLocation];
499769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    if ([theEvent type] == NSMouseMoved)
500769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      webContents->GetDelegate()->ContentsMouseEvent(
501769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis          webContents, gfx::Point(location.x, location.y), true);
502769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    if ([theEvent type] == NSMouseExited)
503fc26107870e0e450d863541179234bf9063a4da7Argyrios Kyrtzidis      webContents->GetDelegate()->ContentsMouseEvent(
504769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis          webContents, gfx::Point(location.x, location.y), false);
505769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
506769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
507769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
508769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (void)setMouseDownCanMoveWindow:(BOOL)canMove {
509769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  mouseDownCanMoveWindow_ = canMove;
510769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
511769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
512769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (BOOL)mouseDownCanMoveWindow {
513769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // This is needed to prevent mouseDowns from moving the window
514769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // around.  The default implementation returns YES only for opaque
515769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // views.  WebContentsViewCocoa does not draw itself in any way, but
516769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // its subviews do paint their entire frames.  Returning NO here
517686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  // saves us the effort of overriding this method in every possible
518769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // subview.
519769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  return mouseDownCanMoveWindow_;
520769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
521769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
522769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (void)pasteboard:(NSPasteboard*)sender provideDataForType:(NSString*)type {
523769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  [dragSource_ lazyWriteToPasteboard:sender
524769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             forType:type];
525769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
526769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
527769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (void)startDragWithDropData:(const DropData&)dropData
52830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis            dragOperationMask:(NSDragOperation)operationMask
529312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                        image:(NSImage*)image
530312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                       offset:(NSPoint)offset {
53130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  dragSource_.reset([[WebDragSource alloc]
532e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      initWithContents:[self webContents]
533af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis                  view:self
534af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis              dropData:&dropData
535cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                 image:image
536cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                offset:offset
537183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis            pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
538183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis     dragOperationMask:operationMask]);
539183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  [dragSource_ startDrag];
540183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
541183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
542183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis// NSDraggingSource methods
543183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
544183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis// Returns what kind of drag operations are available. This is a required
545183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis// method for NSDraggingSource.
546183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal {
547312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  if (dragSource_)
548312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    return [dragSource_ draggingSourceOperationMaskForLocal:isLocal];
549e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  // No web drag source - this is the case for dragging a file from the
550deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  // downloads manager. Default to copy operation. Note: It is desirable to
551dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks  // allow the user to either move or copy, but this requires additional
552dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks  // plumbing to update the download item's path once its moved.
5539be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  return NSDragOperationCopy;
5549be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek}
555deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
556686775deca8b8685eb90801495880e3abdd844c2Chris Lattner// Called when a drag initiated in our view ends.
557deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis- (void)draggedImage:(NSImage*)anImage
558deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis             endedAt:(NSPoint)screenPoint
559deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis           operation:(NSDragOperation)operation {
560deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  [dragSource_ endDragAt:screenPoint operation:operation];
561deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
562deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  // Might as well throw out this object now.
56343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  dragSource_.reset();
56443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis}
56543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
56643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Called when a drag initiated in our view moves.
56743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis- (void)draggedImage:(NSImage*)draggedImage movedTo:(NSPoint)screenPoint {
56843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis}
569769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
570769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Called when a file drag is dropped and the promised files need to be written.
571769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (NSArray*)namesOfPromisedFilesDroppedAtDestination:(NSURL*)dropDest {
572769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (![dropDest isFileURL])
573769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    return nil;
574769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
575769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  NSString* fileName = [dragSource_ dragPromisedFileTo:[dropDest path]];
576769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (!fileName)
577769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    return nil;
578769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
579769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  return @[ fileName ];
580769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
581769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
582769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// NSDraggingDestination methods
583769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
584769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
585769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  return [dragDest_ draggingEntered:sender view:self];
586769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
587769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
588769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (void)draggingExited:(id<NSDraggingInfo>)sender {
589769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  [dragDest_ draggingExited:sender];
590769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
591769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
592769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender {
593769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  return [dragDest_ draggingUpdated:sender view:self];
594769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
59543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
596- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
597  return [dragDest_ performDragOperation:sender view:self];
598}
599
600- (void)cancelDeferredClose {
601  SEL aSel = @selector(closeTabAfterEvent);
602  [NSObject cancelPreviousPerformRequestsWithTarget:self
603                                           selector:aSel
604                                             object:nil];
605}
606
607- (void)clearWebContentsView {
608  webContentsView_ = NULL;
609  [dragSource_ clearWebContentsView];
610}
611
612- (void)closeTabAfterEvent {
613  webContentsView_->CloseTab();
614}
615
616- (void)viewDidBecomeFirstResponder:(NSNotification*)notification {
617  NSView* view = [notification object];
618  if (![[self subviews] containsObject:view])
619    return;
620
621  NSSelectionDirection direction =
622      [[[notification userInfo] objectForKey:kSelectionDirection]
623        unsignedIntegerValue];
624  if (direction == NSDirectSelection)
625    return;
626
627  [self webContents]->
628      FocusThroughTabTraversal(direction == NSSelectingPrevious);
629}
630
631// When the subviews require a layout, their size should be reset to the size
632// of this view. (It is possible for the size to get out of sync as an
633// optimization in preparation for an upcoming WebContentsView resize.
634// http://crbug.com/264207)
635- (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
636  for (NSView* subview in self.subviews)
637    [subview setFrame:self.bounds];
638}
639
640@end
641