 Chromium Code Reviews
 Chromium Code Reviews Issue 1146873002:
  [MacViews] Enable dragging a window by its caption/draggable areas.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1146873002:
  [MacViews] Enable dragging a window by its caption/draggable areas.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| Index: ui/views/cocoa/cocoa_non_client_drag.mm | 
| diff --git a/ui/views/cocoa/cocoa_non_client_drag.mm b/ui/views/cocoa/cocoa_non_client_drag.mm | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..f36e69e8819c1130f2349a439f20b74150ca76e7 | 
| --- /dev/null | 
| +++ b/ui/views/cocoa/cocoa_non_client_drag.mm | 
| @@ -0,0 +1,77 @@ | 
| +// Copyright 2015 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#import "ui/views/cocoa/cocoa_non_client_drag.h" | 
| + | 
| +#import <Cocoa/Cocoa.h> | 
| + | 
| +#include "base/logging.h" | 
| +#import "base/mac/foundation_util.h" | 
| +#include "base/process/process_handle.h" | 
| + | 
| +namespace views { | 
| + | 
| +namespace { | 
| + | 
| +int g_ref_count = 0; | 
| 
jackhou1
2015/05/20 05:50:37
Do we already have something that implements this
 
tapted
2015/05/20 07:18:17
Yeah I would just create it lazily, once, and not
 
jackhou1
2015/05/22 02:49:17
Done.
 | 
| +id g_event_monitor = nil; | 
| +bool is_first_repost = false; | 
| 
tapted
2015/05/20 07:18:18
make this a local static of DoubleRepostEventIfHan
 
jackhou1
2015/05/22 02:49:16
Fortunately, the eventNumber does remain unchanged
 | 
| + | 
| +bool DoubleRepostEventIfHandledByWindow(NSWindow* window, | 
| + NSPoint location, | 
| + CGEventRef event) { | 
| + // If the event was just reposted, repost it again, otherwise it won't work. | 
| + if (is_first_repost) { | 
| + LOG(INFO) << "double reposting " << event; | 
| + is_first_repost = false; | 
| + CGEventPost(kCGSessionEventTap, event); | 
| + return true; | 
| + } | 
| + if ([window respondsToSelector:@selector(willReceiveLeftMouseDown:)] && | 
| 
tapted
2015/05/20 07:18:17
maybe just check if [[window delegate] respondsToS
 
jackhou1
2015/05/22 02:49:17
Done.
 | 
| + [base::mac::ObjCCast<NativeWidgetMacNSWindow>(window) | 
| + willReceiveLeftMouseDown:location]) { | 
| + is_first_repost = true; | 
| + CGEventPost(kCGSessionEventTap, event); | 
| + return true; | 
| + } | 
| + | 
| + return false; | 
| +} | 
| + | 
| +} // namespace | 
| + | 
| +CocoaNonClientDrag::CocoaNonClientDrag() { | 
| + if (g_ref_count) | 
| + return; | 
| + | 
| + NSEvent* (^monitor_callback)(NSEvent* ns_event); | 
| + monitor_callback = ^NSEvent*(NSEvent* ns_event) { | 
| + CGEventRef cg_event = [ns_event CGEvent]; | 
| + LOG(INFO) << "MonitorCallback " << cg_event; | 
| + if (DoubleRepostEventIfHandledByWindow( | 
| 
tapted
2015/05/20 07:18:18
just pass ns_event?
 
jackhou1
2015/05/22 02:49:16
Done.
 | 
| + [ns_event window], [ns_event locationInWindow], cg_event)) { | 
| + return nil; | 
| + } | 
| + return ns_event; | 
| + }; | 
| + | 
| + g_event_monitor = | 
| 
tapted
2015/05/20 07:18:18
I guess this can be a static local too.
 
jackhou1
2015/05/22 02:49:17
Done.
 | 
| + [NSEvent addLocalMonitorForEventsMatchingMask:NSLeftMouseDownMask | 
| + handler:monitor_callback]; | 
| + | 
| + ++g_ref_count; | 
| +} | 
| + | 
| +CocoaNonClientDrag::~CocoaNonClientDrag() { | 
| + --g_ref_count; | 
| 
tapted
2015/05/20 07:18:18
I guess this would just become a NOTREACHED() with
 
jackhou1
2015/05/22 02:49:16
Done.
 | 
| + if (g_ref_count) | 
| + return; | 
| + | 
| + if (g_event_monitor) { | 
| + [NSEvent removeMonitor:g_event_monitor]; | 
| + g_event_monitor = nil; | 
| + } | 
| +} | 
| + | 
| +} // namespace views |