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
3 // found in the LICENSE file.
5 #include "chrome/browser/platform_util.h"
7 #import <Cocoa/Cocoa.h>
10 #include "base/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/logging.h"
13 #include "base/mac/mac_logging.h"
14 #include "base/strings/sys_string_conversions.h"
15 #include "chrome/browser/platform_util_internal.h"
16 #include "content/public/browser/browser_task_traits.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "ui/views/widget/widget.h"
21 namespace platform_util {
23 void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) {
24 DCHECK([NSThread isMainThread]);
25 NSString* path_string = base::SysUTF8ToNSString(full_path.value());
26 if (!path_string || ![[NSWorkspace sharedWorkspace] selectFile:path_string
27 inFileViewerRootedAtPath:@""])
28 LOG(WARNING) << "NSWorkspace failed to select file " << full_path.value();
31 void OpenFileOnMainThread(const base::FilePath& full_path) {
32 DCHECK([NSThread isMainThread]);
33 NSString* path_string = base::SysUTF8ToNSString(full_path.value());
37 // On Mavericks or later, NSWorkspaceLaunchWithErrorPresentation will
38 // properly handle Finder activation for quarantined files
39 // (http://crbug.com/32921) and unassociated file types
40 // (http://crbug.com/50263).
41 NSURL* url = [NSURL fileURLWithPath:path_string];
45 const NSWorkspaceLaunchOptions launch_options =
46 NSWorkspaceLaunchAsync | NSWorkspaceLaunchWithErrorPresentation;
47 [[NSWorkspace sharedWorkspace] openURLs:@[ url ]
48 withAppBundleIdentifier:nil
49 options:launch_options
50 additionalEventParamDescriptor:nil
51 launchIdentifiers:NULL];
56 void PlatformOpenVerifiedItem(const base::FilePath& path, OpenItemType type) {
59 content::GetUIThreadTaskRunner({})->PostTask(
60 FROM_HERE, base::BindOnce(&OpenFileOnMainThread, path));
63 NSString* path_string = base::SysUTF8ToNSString(path.value());
66 // Note that there exists a TOCTOU race between the time that |path| was
67 // verified as being a directory and when NSWorkspace invokes Finder (or
68 // alternative) to open |path_string|.
69 [[NSWorkspace sharedWorkspace] openFile:path_string];
74 } // namespace internal
76 void OpenExternal(Profile* profile, const GURL& url) {
77 DCHECK([NSThread isMainThread]);
78 NSString* url_string = base::SysUTF8ToNSString(url.spec());
79 NSURL* ns_url = [NSURL URLWithString:url_string];
80 if (!ns_url || ![[NSWorkspace sharedWorkspace] openURL:ns_url])
81 LOG(WARNING) << "NSWorkspace failed to open URL " << url;
84 gfx::NativeWindow GetTopLevel(gfx::NativeView view) {
85 return gfx::NativeWindow([view.GetNativeNSView() window]);
88 gfx::NativeView GetViewForWindow(gfx::NativeWindow native_window) {
89 NSWindow* window = native_window.GetNativeNSWindow();
91 DCHECK([window contentView]);
92 return gfx::NativeView([window contentView]);
95 gfx::NativeView GetParent(gfx::NativeView view) {
96 return gfx::NativeView(nil);
99 bool IsWindowActive(gfx::NativeWindow native_window) {
100 // If |window| is a doppelganger NSWindow being used to track an NSWindow that
101 // is being hosted in another process, then use the views::Widget interface to
103 views::Widget* widget =
104 views::Widget::GetWidgetForNativeWindow(native_window);
106 return widget->IsActive();
108 NSWindow* window = native_window.GetNativeNSWindow();
109 return [window isKeyWindow] || [window isMainWindow];
112 void ActivateWindow(gfx::NativeWindow native_window) {
113 views::Widget* widget =
114 views::Widget::GetWidgetForNativeWindow(native_window);
116 return widget->Activate();
118 NSWindow* window = native_window.GetNativeNSWindow();
119 [window makeKeyAndOrderFront:nil];
122 bool IsVisible(gfx::NativeView native_view) {
123 views::Widget* widget = views::Widget::GetWidgetForNativeView(native_view);
125 return widget->IsVisible();
127 // A reasonable approximation of how you'd expect this to behave.
128 NSView* view = native_view.GetNativeNSView();
130 ![view isHiddenOrHasHiddenAncestor] &&
132 [[view window] isVisible]);
135 bool IsSwipeTrackingFromScrollEventsEnabled() {
136 SEL selector = @selector(isSwipeTrackingFromScrollEventsEnabled);
137 return [NSEvent respondsToSelector:selector]
138 && [NSEvent performSelector:selector];
141 } // namespace platform_util