snapshot_mac.mm 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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.
  4. #include "ui/snapshot/snapshot.h"
  5. #import <Cocoa/Cocoa.h>
  6. #include "base/callback.h"
  7. #include "base/check_op.h"
  8. #include "base/mac/scoped_cftyperef.h"
  9. #include "ui/gfx/geometry/rect.h"
  10. #include "ui/gfx/image/image.h"
  11. namespace ui {
  12. bool GrabViewSnapshot(gfx::NativeView native_view,
  13. const gfx::Rect& snapshot_bounds,
  14. gfx::Image* image) {
  15. NSView* view = native_view.GetNativeNSView();
  16. NSWindow* window = [view window];
  17. NSScreen* screen = [[NSScreen screens] firstObject];
  18. gfx::Rect screen_bounds = gfx::Rect(NSRectToCGRect([screen frame]));
  19. // Get the view bounds relative to the screen
  20. NSRect frame = [view convertRect:[view bounds] toView:nil];
  21. frame = [window convertRectToScreen:frame];
  22. gfx::Rect view_bounds = gfx::Rect(NSRectToCGRect(frame));
  23. // Flip window coordinates based on the primary screen.
  24. view_bounds.set_y(
  25. screen_bounds.height() - view_bounds.y() - view_bounds.height());
  26. // Convert snapshot bounds relative to window into bounds relative to
  27. // screen.
  28. gfx::Rect screen_snapshot_bounds = snapshot_bounds;
  29. screen_snapshot_bounds.Offset(view_bounds.OffsetFromOrigin());
  30. DCHECK_LE(screen_snapshot_bounds.right(), view_bounds.right());
  31. DCHECK_LE(screen_snapshot_bounds.bottom(), view_bounds.bottom());
  32. base::ScopedCFTypeRef<CGImageRef> windowSnapshot(
  33. CGWindowListCreateImage(screen_snapshot_bounds.ToCGRect(),
  34. kCGWindowListOptionIncludingWindow,
  35. [window windowNumber],
  36. kCGWindowImageBoundsIgnoreFraming));
  37. if (CGImageGetWidth(windowSnapshot) <= 0)
  38. return false;
  39. *image =
  40. gfx::Image([[[NSImage alloc] initWithCGImage:windowSnapshot
  41. size:NSZeroSize] autorelease]);
  42. return true;
  43. }
  44. bool GrabWindowSnapshot(gfx::NativeWindow native_window,
  45. const gfx::Rect& snapshot_bounds,
  46. gfx::Image* image) {
  47. // Make sure to grab the "window frame" view so we get current tab +
  48. // tabstrip.
  49. NSWindow* window = native_window.GetNativeNSWindow();
  50. return GrabViewSnapshot([[window contentView] superview], snapshot_bounds,
  51. image);
  52. }
  53. void GrabWindowSnapshotAndScaleAsync(
  54. gfx::NativeWindow window,
  55. const gfx::Rect& snapshot_bounds,
  56. const gfx::Size& target_size,
  57. GrabWindowSnapshotAsyncCallback callback) {
  58. std::move(callback).Run(gfx::Image());
  59. }
  60. void GrabViewSnapshotAsync(gfx::NativeView view,
  61. const gfx::Rect& source_rect,
  62. GrabWindowSnapshotAsyncCallback callback) {
  63. std::move(callback).Run(gfx::Image());
  64. }
  65. void GrabWindowSnapshotAsync(gfx::NativeWindow native_window,
  66. const gfx::Rect& source_rect,
  67. GrabWindowSnapshotAsyncCallback callback) {
  68. NSWindow* window = native_window.GetNativeNSWindow();
  69. return GrabViewSnapshotAsync([[window contentView] superview], source_rect,
  70. std::move(callback));
  71. }
  72. } // namespace ui