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

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_mac.mm

Issue 423773002: Unified BeginFrame scheduling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
6 6
7 #import <objc/runtime.h> 7 #import <objc/runtime.h>
8 #include <OpenGL/gl.h> 8 #include <OpenGL/gl.h>
9 #include <QuartzCore/QuartzCore.h> 9 #include <QuartzCore/QuartzCore.h>
10 10
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/callback_helpers.h" 13 #include "base/callback_helpers.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/debug/crash_logging.h" 15 #include "base/debug/crash_logging.h"
16 #include "base/debug/trace_event.h" 16 #include "base/debug/trace_event.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/mac/mac_util.h" 18 #include "base/mac/mac_util.h"
19 #include "base/mac/scoped_cftyperef.h" 19 #include "base/mac/scoped_cftyperef.h"
20 #import "base/mac/scoped_nsobject.h" 20 #import "base/mac/scoped_nsobject.h"
21 #include "base/mac/sdk_forward_declarations.h" 21 #include "base/mac/sdk_forward_declarations.h"
22 #include "base/message_loop/message_loop.h" 22 #include "base/message_loop/message_loop.h"
23 #include "base/metrics/histogram.h" 23 #include "base/metrics/histogram.h"
24 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
25 #include "base/strings/stringprintf.h" 25 #include "base/strings/stringprintf.h"
26 #include "base/strings/sys_string_conversions.h" 26 #include "base/strings/sys_string_conversions.h"
27 #include "base/strings/utf_string_conversions.h" 27 #include "base/strings/utf_string_conversions.h"
28 #include "base/sys_info.h" 28 #include "base/sys_info.h"
29 #include "cc/base/switches.h"
29 #import "content/browser/accessibility/browser_accessibility_cocoa.h" 30 #import "content/browser/accessibility/browser_accessibility_cocoa.h"
30 #include "content/browser/accessibility/browser_accessibility_manager_mac.h" 31 #include "content/browser/accessibility/browser_accessibility_manager_mac.h"
31 #import "content/browser/cocoa/system_hotkey_helper_mac.h" 32 #import "content/browser/cocoa/system_hotkey_helper_mac.h"
32 #import "content/browser/cocoa/system_hotkey_map.h" 33 #import "content/browser/cocoa/system_hotkey_map.h"
33 #include "content/browser/compositor/resize_lock.h" 34 #include "content/browser/compositor/resize_lock.h"
34 #include "content/browser/frame_host/frame_tree.h" 35 #include "content/browser/frame_host/frame_tree.h"
35 #include "content/browser/frame_host/frame_tree_node.h" 36 #include "content/browser/frame_host/frame_tree_node.h"
36 #include "content/browser/frame_host/render_frame_host_impl.h" 37 #include "content/browser/frame_host/render_frame_host_impl.h"
37 #include "content/browser/gpu/compositor_util.h" 38 #include "content/browser/gpu/compositor_util.h"
38 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" 39 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 : render_widget_host_(RenderWidgetHostImpl::From(widget)), 505 : render_widget_host_(RenderWidgetHostImpl::From(widget)),
505 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), 506 text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
506 can_compose_inline_(true), 507 can_compose_inline_(true),
507 browser_compositor_view_placeholder_( 508 browser_compositor_view_placeholder_(
508 new BrowserCompositorViewPlaceholderMac), 509 new BrowserCompositorViewPlaceholderMac),
509 backing_store_scale_factor_(1), 510 backing_store_scale_factor_(1),
510 is_loading_(false), 511 is_loading_(false),
511 allow_pause_for_resize_or_repaint_(true), 512 allow_pause_for_resize_or_repaint_(true),
512 weak_factory_(this), 513 weak_factory_(this),
513 fullscreen_parent_host_view_(NULL), 514 fullscreen_parent_host_view_(NULL),
515 needs_begin_frame_(false),
514 software_frame_weak_ptr_factory_(this) { 516 software_frame_weak_ptr_factory_(this) {
515 software_frame_manager_.reset(new SoftwareFrameManager( 517 software_frame_manager_.reset(new SoftwareFrameManager(
516 software_frame_weak_ptr_factory_.GetWeakPtr())); 518 software_frame_weak_ptr_factory_.GetWeakPtr()));
517 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| 519 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_|
518 // goes away. Since we autorelease it, our caller must put 520 // goes away. Since we autorelease it, our caller must put
519 // |GetNativeView()| into the view hierarchy right after calling us. 521 // |GetNativeView()| into the view hierarchy right after calling us.
520 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] 522 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc]
521 initWithRenderWidgetHostViewMac:this] autorelease]; 523 initWithRenderWidgetHostViewMac:this] autorelease];
522 524
523 // Make this view host a solid white layer when there is no content ready to 525 // Make this view host a solid white layer when there is no content ready to
(...skipping 19 matching lines...) Expand all
543 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED)); 545 root_layer_.reset(new ui::Layer(ui::LAYER_TEXTURED));
544 delegated_frame_host_.reset(new DelegatedFrameHost(this)); 546 delegated_frame_host_.reset(new DelegatedFrameHost(this));
545 } 547 }
546 548
547 gfx::Screen::GetScreenFor(cocoa_view_)->AddObserver(this); 549 gfx::Screen::GetScreenFor(cocoa_view_)->AddObserver(this);
548 550
549 render_widget_host_->SetView(this); 551 render_widget_host_->SetView(this);
550 } 552 }
551 553
552 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { 554 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() {
555 if (display_link_) {
556 DCHECK(needs_begin_frame_);
557 display_link_->RemoveObserver(this);
558 }
553 gfx::Screen::GetScreenFor(cocoa_view_)->RemoveObserver(this); 559 gfx::Screen::GetScreenFor(cocoa_view_)->RemoveObserver(this);
554 560
555 // This is being called from |cocoa_view_|'s destructor, so invalidate the 561 // This is being called from |cocoa_view_|'s destructor, so invalidate the
556 // pointer. 562 // pointer.
557 cocoa_view_ = nil; 563 cocoa_view_ = nil;
558 564
559 UnlockMouse(); 565 UnlockMouse();
560 566
561 // Make sure that the layer doesn't reach into the now-invalid object. 567 // Make sure that the layer doesn't reach into the now-invalid object.
562 DestroyCompositedIOSurfaceAndLayer(); 568 DestroyCompositedIOSurfaceAndLayer();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 if (!delegated_frame_host_) 650 if (!delegated_frame_host_)
645 return; 651 return;
646 if (browser_compositor_view_) 652 if (browser_compositor_view_)
647 return; 653 return;
648 654
649 TRACE_EVENT0("browser", 655 TRACE_EVENT0("browser",
650 "RenderWidgetHostViewMac::EnsureBrowserCompositorView"); 656 "RenderWidgetHostViewMac::EnsureBrowserCompositorView");
651 657
652 browser_compositor_view_.reset(new BrowserCompositorViewMac(this)); 658 browser_compositor_view_.reset(new BrowserCompositorViewMac(this));
653 delegated_frame_host_->AddedToWindow(); 659 delegated_frame_host_->AddedToWindow();
654 delegated_frame_host_->WasShown(); 660 delegated_frame_host_->WasShown(ui::LatencyInfo());
brianderson 2014/09/04 18:45:46 Why pass ui::LatencyInfo() now?
661
662 if (needs_begin_frame_)
663 GetCompositor()->AddBeginFrameObserver(this, last_begin_frame_args_);
655 } 664 }
656 665
657 void RenderWidgetHostViewMac::DestroyBrowserCompositorView() { 666 void RenderWidgetHostViewMac::DestroyBrowserCompositorView() {
658 TRACE_EVENT0("browser", 667 TRACE_EVENT0("browser",
659 "RenderWidgetHostViewMac::DestroyBrowserCompositorView"); 668 "RenderWidgetHostViewMac::DestroyBrowserCompositorView");
660 if (!browser_compositor_view_) 669 if (!browser_compositor_view_)
661 return; 670 return;
662 671
663 delegated_frame_host_->WasHidden(); 672 delegated_frame_host_->WasHidden();
664 delegated_frame_host_->RemovingFromWindow(); 673 delegated_frame_host_->RemovingFromWindow();
665 browser_compositor_view_.reset(); 674 browser_compositor_view_.reset();
675
676 if (needs_begin_frame_) {
677 GetCompositor()->RemoveBeginFrameObserver(this);
678 needs_begin_frame_ = false;
679 }
666 } 680 }
667 681
668 void RenderWidgetHostViewMac::EnsureSoftwareLayer() { 682 void RenderWidgetHostViewMac::EnsureSoftwareLayer() {
669 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::EnsureSoftwareLayer"); 683 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::EnsureSoftwareLayer");
670 if (software_layer_) 684 if (software_layer_)
671 return; 685 return;
672 686
673 software_layer_.reset([[SoftwareLayer alloc] init]); 687 software_layer_.reset([[SoftwareLayer alloc] init]);
674 DCHECK(software_layer_); 688 DCHECK(software_layer_);
675 689
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 DestroyCompositedIOSurfaceLayer(kRemoveLayerFromHierarchy); 741 DestroyCompositedIOSurfaceLayer(kRemoveLayerFromHierarchy);
728 compositing_iosurface_ = NULL; 742 compositing_iosurface_ = NULL;
729 compositing_iosurface_context_ = NULL; 743 compositing_iosurface_context_ = NULL;
730 } 744 }
731 745
732 bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) { 746 bool RenderWidgetHostViewMac::OnMessageReceived(const IPC::Message& message) {
733 bool handled = true; 747 bool handled = true;
734 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message) 748 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewMac, message)
735 IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged) 749 IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnPluginFocusChanged)
736 IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme) 750 IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, OnStartPluginIme)
751 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrame, OnSetNeedsBeginFrame)
737 IPC_MESSAGE_UNHANDLED(handled = false) 752 IPC_MESSAGE_UNHANDLED(handled = false)
738 IPC_END_MESSAGE_MAP() 753 IPC_END_MESSAGE_MAP()
739 return handled; 754 return handled;
740 } 755 }
741 756
742 void RenderWidgetHostViewMac::InitAsChild( 757 void RenderWidgetHostViewMac::InitAsChild(
743 gfx::NativeView parent_view) { 758 gfx::NativeView parent_view) {
744 } 759 }
745 760
746 void RenderWidgetHostViewMac::InitAsPopup( 761 void RenderWidgetHostViewMac::InitAsPopup(
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 NSScreen* screen = [[cocoa_view_ window] screen]; 866 NSScreen* screen = [[cocoa_view_ window] screen];
852 NSDictionary* screen_description = [screen deviceDescription]; 867 NSDictionary* screen_description = [screen deviceDescription];
853 NSNumber* screen_number = [screen_description objectForKey:@"NSScreenNumber"]; 868 NSNumber* screen_number = [screen_description objectForKey:@"NSScreenNumber"];
854 CGDirectDisplayID display_id = [screen_number unsignedIntValue]; 869 CGDirectDisplayID display_id = [screen_number unsignedIntValue];
855 870
856 display_link_ = DisplayLinkMac::GetForDisplay(display_id); 871 display_link_ = DisplayLinkMac::GetForDisplay(display_id);
857 if (!display_link_) { 872 if (!display_link_) {
858 // Note that on some headless systems, the display link will fail to be 873 // Note that on some headless systems, the display link will fail to be
859 // created, so this should not be a fatal error. 874 // created, so this should not be a fatal error.
860 LOG(ERROR) << "Failed to create display link."; 875 LOG(ERROR) << "Failed to create display link.";
861 }
862 }
863
864 void RenderWidgetHostViewMac::SendVSyncParametersToRenderer() {
865 if (!render_widget_host_ || !display_link_)
866 return;
867
868 if (!display_link_->GetVSyncParameters(&vsync_timebase_, &vsync_interval_)) {
869 vsync_timebase_ = base::TimeTicks();
870 vsync_interval_ = base::TimeDelta();
871 return; 876 return;
872 } 877 }
873 878
874 render_widget_host_->UpdateVSyncParameters(vsync_timebase_, vsync_interval_); 879 display_link_->AddObserver(this);
880 }
881
882 void RenderWidgetHostViewMac::OnSetNeedsBeginFrame(bool enabled) {
883 DCHECK(display_link_);
884
885 if (needs_begin_frame_ == enabled)
886 return;
887
888 TRACE_EVENT1("cc", "RenderWidgetHostViewMac::OnSetNeedsBeginFrame",
889 "enabled", enabled);
890
891 needs_begin_frame_ = enabled;
892
893 if (enabled)
894 GetCompositor()->AddBeginFrameObserver(this, last_begin_frame_args_);
895 else
896 DCHECK(!GetCompsoitr());
brianderson 2014/09/04 18:45:46 RemoveBeginFrameObserver?
875 } 897 }
876 898
877 void RenderWidgetHostViewMac::UpdateBackingStoreScaleFactor() { 899 void RenderWidgetHostViewMac::UpdateBackingStoreScaleFactor() {
878 if (!render_widget_host_) 900 if (!render_widget_host_)
879 return; 901 return;
880 902
881 float new_scale_factor = ui::GetScaleFactorForNativeView(cocoa_view_); 903 float new_scale_factor = ui::GetScaleFactorForNativeView(cocoa_view_);
882 if (new_scale_factor == backing_store_scale_factor_) 904 if (new_scale_factor == backing_store_scale_factor_)
883 return; 905 return;
884 backing_store_scale_factor_ = new_scale_factor; 906 backing_store_scale_factor_ = new_scale_factor;
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after
1851 gfx::Size dip_size = 1873 gfx::Size dip_size =
1852 ConvertSizeToDIP(scale_factor, pixel_size); 1874 ConvertSizeToDIP(scale_factor, pixel_size);
1853 1875
1854 root_layer_->SetBounds(gfx::Rect(dip_size)); 1876 root_layer_->SetBounds(gfx::Rect(dip_size));
1855 if (!render_widget_host_->is_hidden()) { 1877 if (!render_widget_host_->is_hidden()) {
1856 EnsureBrowserCompositorView(); 1878 EnsureBrowserCompositorView();
1857 browser_compositor_view_->GetCompositor()->SetScaleAndSize( 1879 browser_compositor_view_->GetCompositor()->SetScaleAndSize(
1858 scale_factor, pixel_size); 1880 scale_factor, pixel_size);
1859 } 1881 }
1860 1882
1861 SendVSyncParametersToRenderer();
1862
1863 delegated_frame_host_->SwapDelegatedFrame( 1883 delegated_frame_host_->SwapDelegatedFrame(
1864 output_surface_id, 1884 output_surface_id,
1865 frame->delegated_frame_data.Pass(), 1885 frame->delegated_frame_data.Pass(),
1866 frame->metadata.device_scale_factor, 1886 frame->metadata.device_scale_factor,
1867 frame->metadata.latency_info); 1887 frame->metadata.latency_info);
1868 } else if (frame->software_frame_data) { 1888 } else if (frame->software_frame_data) {
1869 if (!software_frame_manager_->SwapToNewFrame( 1889 if (!software_frame_manager_->SwapToNewFrame(
1870 output_surface_id, 1890 output_surface_id,
1871 frame->software_frame_data.get(), 1891 frame->software_frame_data.get(),
1872 frame->metadata.device_scale_factor, 1892 frame->metadata.device_scale_factor,
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 } 2027 }
2008 2028
2009 void RenderWidgetHostViewMac::ShutdownHost() { 2029 void RenderWidgetHostViewMac::ShutdownHost() {
2010 weak_factory_.InvalidateWeakPtrs(); 2030 weak_factory_.InvalidateWeakPtrs();
2011 render_widget_host_->Shutdown(); 2031 render_widget_host_->Shutdown();
2012 // Do not touch any members at this point, |this| has been deleted. 2032 // Do not touch any members at this point, |this| has been deleted.
2013 } 2033 }
2014 2034
2015 void RenderWidgetHostViewMac::GotAcceleratedFrame() { 2035 void RenderWidgetHostViewMac::GotAcceleratedFrame() {
2016 EnsureCompositedIOSurfaceLayer(); 2036 EnsureCompositedIOSurfaceLayer();
2017 SendVSyncParametersToRenderer();
2018 2037
2019 // Delete software backingstore and layer. 2038 // Delete software backingstore and layer.
2020 software_frame_manager_->DiscardCurrentFrame(); 2039 software_frame_manager_->DiscardCurrentFrame();
2021 DestroySoftwareLayer(); 2040 DestroySoftwareLayer();
2022 } 2041 }
2023 2042
2024 void RenderWidgetHostViewMac::GotSoftwareFrame() { 2043 void RenderWidgetHostViewMac::GotSoftwareFrame() {
2025 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::GotSoftwareFrame"); 2044 TRACE_EVENT0("browser", "RenderWidgetHostViewMac::GotSoftwareFrame");
2026 2045
2027 if (!render_widget_host_) 2046 if (!render_widget_host_)
2028 return; 2047 return;
2029 2048
2030 EnsureSoftwareLayer(); 2049 EnsureSoftwareLayer();
2031 LayoutLayers(); 2050 LayoutLayers();
2032 SendVSyncParametersToRenderer();
2033 2051
2034 // Draw the contents of the frame immediately. It is critical that this 2052 // Draw the contents of the frame immediately. It is critical that this
2035 // happen before the frame be acked, otherwise the new frame will likely be 2053 // happen before the frame be acked, otherwise the new frame will likely be
2036 // ready before the drawing is complete, thrashing the browser main thread. 2054 // ready before the drawing is complete, thrashing the browser main thread.
2037 [software_layer_ displayIfNeeded]; 2055 [software_layer_ displayIfNeeded];
2038 2056
2039 DestroyCompositedIOSurfaceAndLayer(); 2057 DestroyCompositedIOSurfaceAndLayer();
2040 } 2058 }
2041 2059
2042 void RenderWidgetHostViewMac::SetActive(bool active) { 2060 void RenderWidgetHostViewMac::SetActive(bool active) {
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2335 2353
2336 void RenderWidgetHostViewMac::OnDisplayMetricsChanged( 2354 void RenderWidgetHostViewMac::OnDisplayMetricsChanged(
2337 const gfx::Display& display, uint32_t metrics) { 2355 const gfx::Display& display, uint32_t metrics) {
2338 gfx::Screen* screen = gfx::Screen::GetScreenFor(cocoa_view_); 2356 gfx::Screen* screen = gfx::Screen::GetScreenFor(cocoa_view_);
2339 if (display.id() != screen->GetDisplayNearestWindow(cocoa_view_).id()) 2357 if (display.id() != screen->GetDisplayNearestWindow(cocoa_view_).id())
2340 return; 2358 return;
2341 2359
2342 UpdateScreenInfo(cocoa_view_); 2360 UpdateScreenInfo(cocoa_view_);
2343 } 2361 }
2344 2362
2363 void RenderWidgetHostViewMac::OnSendBeginFrame(
2364 const cc::BeginFrameArgs& args) {
2365 DCHECK(display_link_);
2366 DCHECK(render_widget_host_);
2367 TRACE_EVENT0("cc", "RenderWidgetHostViewMac::OnSendBeginFrame");
2368
2369 delegated_frame_host_->UpdateVSyncParameters(args);
2370
2371 render_widget_host_->Send(
2372 new ViewMsg_BeginFrame(render_widget_host_->GetRoutingID(), args));
2373 last_begin_frame_args_ = args;
2374 vsync_timebase_ = args.frame_time;
2375 vsync_interval_ = args.interval;
2376 }
2377
2378 void RenderWidgetHostViewMac::OnVSync(base::TimeTicks timebase,
2379 base::TimeDelta interval) {
2380 DCHECK(display_link_);
2381
2382 if (!GetCompositor())
2383 return;
2384
2385 GetCompositor()->StartBeginFrame(cc::BeginFrameArgs::Create(timebase,
2386 timebase + interval,
2387 interval));
2388 }
2389
2345 } // namespace content 2390 } // namespace content
2346 2391
2347 // RenderWidgetHostViewCocoa --------------------------------------------------- 2392 // RenderWidgetHostViewCocoa ---------------------------------------------------
2348 2393
2349 @implementation RenderWidgetHostViewCocoa 2394 @implementation RenderWidgetHostViewCocoa
2350 @synthesize selectedRange = selectedRange_; 2395 @synthesize selectedRange = selectedRange_;
2351 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_; 2396 @synthesize suppressNextEscapeKeyUp = suppressNextEscapeKeyUp_;
2352 @synthesize markedRange = markedRange_; 2397 @synthesize markedRange = markedRange_;
2353 2398
2354 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { 2399 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r {
(...skipping 1682 matching lines...) Expand 10 before | Expand all | Expand 10 after
4037 4082
4038 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding 4083 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding
4039 // regions that are not draggable. (See ControlRegionView in 4084 // regions that are not draggable. (See ControlRegionView in
4040 // native_app_window_cocoa.mm). This requires the render host view to be 4085 // native_app_window_cocoa.mm). This requires the render host view to be
4041 // draggable by default. 4086 // draggable by default.
4042 - (BOOL)mouseDownCanMoveWindow { 4087 - (BOOL)mouseDownCanMoveWindow {
4043 return YES; 4088 return YES;
4044 } 4089 }
4045 4090
4046 @end 4091 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698