scoped_fake_nswindow_focus.mm 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright 2015 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. #import "ui/base/test/scoped_fake_nswindow_focus.h"
  5. #import <Cocoa/Cocoa.h>
  6. #import "base/mac/foundation_util.h"
  7. #import "base/mac/scoped_objc_class_swizzler.h"
  8. using base::mac::ScopedObjCClassSwizzler;
  9. namespace {
  10. NSWindow* g_fake_focused_window = nil;
  11. base::mac::ScopedObjCClassSwizzler* g_order_out_swizzler = nullptr;
  12. void SetFocus(NSWindow* window) {
  13. g_fake_focused_window = window;
  14. [[NSNotificationCenter defaultCenter]
  15. postNotificationName:NSWindowDidBecomeMainNotification
  16. object:g_fake_focused_window];
  17. [[NSNotificationCenter defaultCenter]
  18. postNotificationName:NSWindowDidBecomeKeyNotification
  19. object:g_fake_focused_window];
  20. }
  21. void ClearFocus() {
  22. NSWindow* window = g_fake_focused_window;
  23. g_fake_focused_window = nil;
  24. [[NSNotificationCenter defaultCenter]
  25. postNotificationName:NSWindowDidResignKeyNotification
  26. object:window];
  27. [[NSNotificationCenter defaultCenter]
  28. postNotificationName:NSWindowDidResignMainNotification
  29. object:window];
  30. }
  31. } // namespace
  32. // Donates testing implementations of NSWindow methods.
  33. @interface FakeNSWindowFocusDonor : NSObject
  34. @end
  35. @implementation FakeNSWindowFocusDonor
  36. - (BOOL)isKeyWindow {
  37. NSWindow* selfAsWindow = base::mac::ObjCCastStrict<NSWindow>(self);
  38. return selfAsWindow == g_fake_focused_window;
  39. }
  40. - (BOOL)isMainWindow {
  41. NSWindow* selfAsWindow = base::mac::ObjCCastStrict<NSWindow>(self);
  42. return selfAsWindow == g_fake_focused_window;
  43. }
  44. - (void)makeKeyWindow {
  45. NSWindow* selfAsWindow = base::mac::ObjCCastStrict<NSWindow>(self);
  46. if (selfAsWindow == g_fake_focused_window ||
  47. ![selfAsWindow canBecomeKeyWindow])
  48. return;
  49. ClearFocus();
  50. SetFocus(selfAsWindow);
  51. }
  52. - (void)makeMainWindow {
  53. [self makeKeyWindow];
  54. }
  55. - (void)orderOut:(id)sender {
  56. NSWindow* selfAsWindow = base::mac::ObjCCastStrict<NSWindow>(self);
  57. if (selfAsWindow == g_fake_focused_window)
  58. ClearFocus();
  59. g_order_out_swizzler->InvokeOriginal<void, id>(self, _cmd, sender);
  60. }
  61. - (void)resignKeyWindow {
  62. }
  63. - (void)resignMainWindow {
  64. }
  65. @end
  66. namespace ui {
  67. namespace test {
  68. ScopedFakeNSWindowFocus::ScopedFakeNSWindowFocus()
  69. : is_main_swizzler_(
  70. new ScopedObjCClassSwizzler([NSWindow class],
  71. [FakeNSWindowFocusDonor class],
  72. @selector(isMainWindow))),
  73. make_main_swizzler_(
  74. new ScopedObjCClassSwizzler([NSWindow class],
  75. [FakeNSWindowFocusDonor class],
  76. @selector(makeMainWindow))),
  77. resign_main_swizzler_(
  78. new ScopedObjCClassSwizzler([NSWindow class],
  79. [FakeNSWindowFocusDonor class],
  80. @selector(resignMainWindow))),
  81. is_key_swizzler_(
  82. new ScopedObjCClassSwizzler([NSWindow class],
  83. [FakeNSWindowFocusDonor class],
  84. @selector(isKeyWindow))),
  85. make_key_swizzler_(
  86. new ScopedObjCClassSwizzler([NSWindow class],
  87. [FakeNSWindowFocusDonor class],
  88. @selector(makeKeyWindow))),
  89. resign_key_swizzler_(
  90. new ScopedObjCClassSwizzler([NSWindow class],
  91. [FakeNSWindowFocusDonor class],
  92. @selector(resignKeyWindow))),
  93. order_out_swizzler_(
  94. new ScopedObjCClassSwizzler([NSWindow class],
  95. [FakeNSWindowFocusDonor class],
  96. @selector(orderOut:))) {
  97. g_order_out_swizzler = order_out_swizzler_.get();
  98. }
  99. ScopedFakeNSWindowFocus::~ScopedFakeNSWindowFocus() {
  100. g_order_out_swizzler = nullptr;
  101. ClearFocus();
  102. }
  103. } // namespace test
  104. } // namespace ui