WindowObserver_mac.mm 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "WindowObserver_mac.h"
  9. #include <AppKit/AppKit.h>
  10. #include <QApplication>
  11. #include <QtGui/qpa/qplatformnativeinterface.h>
  12. @interface NSWindowObserver : NSObject
  13. {
  14. Editor::WindowObserver* m_observer;
  15. NSWindow* m_window;
  16. }
  17. @end
  18. @implementation NSWindowObserver
  19. - (id)initWithWindow:(NSWindow*)window :(Editor::WindowObserver*)observer
  20. {
  21. if ((self = [super init])) {
  22. m_observer = observer;
  23. m_window = window;
  24. [[NSNotificationCenter defaultCenter] addObserver:self
  25. selector:@selector(onWindowWillMove)
  26. name:NSWindowWillMoveNotification
  27. object:m_window];
  28. [[NSNotificationCenter defaultCenter] addObserver:self
  29. selector:@selector(onWindowDidMove)
  30. name:NSWindowDidMoveNotification
  31. object:m_window];
  32. [[NSNotificationCenter defaultCenter] addObserver:self
  33. selector:@selector(onWindowWillStartLiveResize)
  34. name:NSWindowWillStartLiveResizeNotification
  35. object:m_window];
  36. [[NSNotificationCenter defaultCenter] addObserver:self
  37. selector:@selector(onWindowDidLiveResize)
  38. name:NSWindowDidEndLiveResizeNotification
  39. object:m_window];
  40. }
  41. return self;
  42. }
  43. -(void) dealloc
  44. {
  45. [[NSNotificationCenter defaultCenter] removeObserver:self];
  46. [super dealloc];
  47. }
  48. - (void)onWindowWillMove
  49. {
  50. m_observer->setWindowIsMoving(true);
  51. // This notification only indicates that the window is likely to move because the used clicked
  52. // the title bar. If the user releases the mouse without moving the title bar we won't receive
  53. // a NSWindowDidMoveNotification, so we add an additional observer to check the state of the
  54. // mouse. Note that we don't care whether the window moved or not, we just want to be able to
  55. // disable rendering when it is likely
  56. [[NSNotificationCenter defaultCenter] addObserver:self
  57. selector:@selector(onWindowDidUpdate:)
  58. name:NSWindowDidUpdateNotification
  59. object:m_window];
  60. }
  61. - (void)onWindowDidMove
  62. {
  63. m_observer->setWindowIsMoving(false);
  64. [[NSNotificationCenter defaultCenter] removeObserver:self
  65. name:NSWindowDidUpdateNotification
  66. object:m_window];
  67. }
  68. - (void)onWindowDidUpdate:(NSNotification*)notification
  69. {
  70. static const unsigned long leftMouseButton = 1; // a value of 1 << 0 corresponds to the left mouse button
  71. if (([NSEvent pressedMouseButtons] & leftMouseButton) == 0)
  72. {
  73. m_observer->setWindowIsMoving(false);
  74. [[NSNotificationCenter defaultCenter] removeObserver:self
  75. name:NSWindowDidUpdateNotification
  76. object:m_window];
  77. }
  78. }
  79. - (void)onWindowWillStartLiveResize
  80. {
  81. m_observer->setWindowIsResizing(true);
  82. }
  83. - (void)onWindowDidLiveResize
  84. {
  85. m_observer->setWindowIsResizing(false);
  86. }
  87. @end
  88. namespace Editor
  89. {
  90. WindowObserver::WindowObserver(QWindow* window, QObject* parent)
  91. : QObject(parent)
  92. , m_windowIsMoving(false)
  93. , m_windowIsResizing(false)
  94. , m_windowObserver(nullptr)
  95. {
  96. if (!window)
  97. {
  98. return;
  99. }
  100. QPlatformNativeInterface* nativeInterface = QApplication::platformNativeInterface();
  101. NSWindow* nsWindow = static_cast<NSWindow*>(nativeInterface->nativeResourceForWindow("nswindow", window));
  102. if (nsWindow == nullptr)
  103. {
  104. return;
  105. }
  106. m_windowObserver = [[NSWindowObserver alloc] initWithWindow:nsWindow:this];
  107. }
  108. WindowObserver::~WindowObserver()
  109. {
  110. if (m_windowObserver != nil)
  111. {
  112. [m_windowObserver release];
  113. m_windowObserver = nil;
  114. }
  115. }
  116. void WindowObserver::setWindowIsMoving(bool isMoving)
  117. {
  118. if (isMoving == m_windowIsMoving)
  119. {
  120. return;
  121. }
  122. const bool wasMovingOrResizing = m_windowIsMoving || m_windowIsResizing;
  123. m_windowIsMoving = isMoving;
  124. const bool isMovingOrResizing = m_windowIsMoving || m_windowIsResizing;
  125. if (isMovingOrResizing != wasMovingOrResizing)
  126. {
  127. emit windowIsMovingOrResizingChanged(isMovingOrResizing);
  128. }
  129. }
  130. void WindowObserver::setWindowIsResizing(bool isResizing)
  131. {
  132. if (isResizing == m_windowIsResizing)
  133. {
  134. return;
  135. }
  136. const bool wasMovingOrResizing = m_windowIsMoving || m_windowIsResizing;
  137. m_windowIsResizing = isResizing;
  138. const bool isMovingOrResizing = m_windowIsMoving || m_windowIsResizing;
  139. if (isMovingOrResizing != wasMovingOrResizing)
  140. {
  141. emit windowIsMovingOrResizingChanged(isMovingOrResizing);
  142. }
  143. }
  144. }
  145. #include <moc_WindowObserver_mac.cpp>