nsNativeAppSupportCocoa.mm 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "nsString.h"
  6. #import <CoreServices/CoreServices.h>
  7. #import <Cocoa/Cocoa.h>
  8. #include "nsCOMPtr.h"
  9. #include "nsCocoaFeatures.h"
  10. #include "nsNativeAppSupportBase.h"
  11. #include "nsIAppShellService.h"
  12. #include "nsIAppStartup.h"
  13. #include "nsIBaseWindow.h"
  14. #include "nsICommandLineRunner.h"
  15. #include "mozIDOMWindow.h"
  16. #include "nsIDocShellTreeItem.h"
  17. #include "nsIDocShellTreeOwner.h"
  18. #include "nsIInterfaceRequestorUtils.h"
  19. #include "nsIObserver.h"
  20. #include "nsIServiceManager.h"
  21. #include "nsIWebNavigation.h"
  22. #include "nsIWidget.h"
  23. #include "nsIWindowMediator.h"
  24. // This must be included last:
  25. #include "nsObjCExceptions.h"
  26. nsresult
  27. GetNativeWindowPointerFromDOMWindow(mozIDOMWindowProxy *a_window, NSWindow **a_nativeWindow)
  28. {
  29. *a_nativeWindow = nil;
  30. if (!a_window)
  31. return NS_ERROR_INVALID_ARG;
  32. nsCOMPtr<nsIWebNavigation> mruWebNav(do_GetInterface(a_window));
  33. if (mruWebNav) {
  34. nsCOMPtr<nsIDocShellTreeItem> mruTreeItem(do_QueryInterface(mruWebNav));
  35. nsCOMPtr<nsIDocShellTreeOwner> mruTreeOwner = nullptr;
  36. mruTreeItem->GetTreeOwner(getter_AddRefs(mruTreeOwner));
  37. if(mruTreeOwner) {
  38. nsCOMPtr<nsIBaseWindow> mruBaseWindow(do_QueryInterface(mruTreeOwner));
  39. if (mruBaseWindow) {
  40. nsCOMPtr<nsIWidget> mruWidget = nullptr;
  41. mruBaseWindow->GetMainWidget(getter_AddRefs(mruWidget));
  42. if (mruWidget) {
  43. *a_nativeWindow = (NSWindow*)mruWidget->GetNativeData(NS_NATIVE_WINDOW);
  44. }
  45. }
  46. }
  47. }
  48. return NS_OK;
  49. }
  50. class nsNativeAppSupportCocoa : public nsNativeAppSupportBase
  51. {
  52. public:
  53. nsNativeAppSupportCocoa() :
  54. mCanShowUI(false) { }
  55. NS_IMETHOD Start(bool* aRetVal);
  56. NS_IMETHOD ReOpen();
  57. NS_IMETHOD Enable();
  58. private:
  59. bool mCanShowUI;
  60. };
  61. NS_IMETHODIMP
  62. nsNativeAppSupportCocoa::Enable()
  63. {
  64. mCanShowUI = true;
  65. return NS_OK;
  66. }
  67. NS_IMETHODIMP nsNativeAppSupportCocoa::Start(bool *_retval)
  68. {
  69. int major, minor, bugfix;
  70. nsCocoaFeatures::GetSystemVersion(major, minor, bugfix);
  71. NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
  72. // Check that the OS version is supported, if not return false,
  73. // which will make the browser quit. In principle we could display an
  74. // alert here. But the alert's message and buttons would require custom
  75. // localization. So (for now at least) we just log an English message
  76. // to the console before quitting.
  77. if (major < 10 || minor < 6) {
  78. NSLog(@"Minimum OS version requirement not met!");
  79. return NS_OK;
  80. }
  81. *_retval = true;
  82. return NS_OK;
  83. NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
  84. }
  85. NS_IMETHODIMP
  86. nsNativeAppSupportCocoa::ReOpen()
  87. {
  88. NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
  89. if (!mCanShowUI)
  90. return NS_ERROR_FAILURE;
  91. bool haveNonMiniaturized = false;
  92. bool haveOpenWindows = false;
  93. bool done = false;
  94. nsCOMPtr<nsIWindowMediator>
  95. wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
  96. if (!wm) {
  97. return NS_ERROR_FAILURE;
  98. }
  99. else {
  100. nsCOMPtr<nsISimpleEnumerator> windowList;
  101. wm->GetXULWindowEnumerator(nullptr, getter_AddRefs(windowList));
  102. bool more;
  103. windowList->HasMoreElements(&more);
  104. while (more) {
  105. nsCOMPtr<nsISupports> nextWindow = nullptr;
  106. windowList->GetNext(getter_AddRefs(nextWindow));
  107. nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(nextWindow));
  108. if (!baseWindow) {
  109. windowList->HasMoreElements(&more);
  110. continue;
  111. }
  112. else {
  113. haveOpenWindows = true;
  114. }
  115. nsCOMPtr<nsIWidget> widget = nullptr;
  116. baseWindow->GetMainWidget(getter_AddRefs(widget));
  117. if (!widget) {
  118. windowList->HasMoreElements(&more);
  119. continue;
  120. }
  121. NSWindow *cocoaWindow = (NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
  122. if (![cocoaWindow isMiniaturized]) {
  123. haveNonMiniaturized = true;
  124. break; //have un-minimized windows, nothing to do
  125. }
  126. windowList->HasMoreElements(&more);
  127. } // end while
  128. if (!haveNonMiniaturized) {
  129. // Deminiaturize the most recenty used window
  130. nsCOMPtr<mozIDOMWindowProxy> mru;
  131. wm->GetMostRecentWindow(nullptr, getter_AddRefs(mru));
  132. if (mru) {
  133. NSWindow *cocoaMru = nil;
  134. GetNativeWindowPointerFromDOMWindow(mru, &cocoaMru);
  135. if (cocoaMru) {
  136. [cocoaMru deminiaturize:nil];
  137. done = true;
  138. }
  139. }
  140. } // end if have non miniaturized
  141. if (!haveOpenWindows && !done) {
  142. char* argv[] = { nullptr };
  143. // use an empty command line to make the right kind(s) of window open
  144. nsCOMPtr<nsICommandLineRunner> cmdLine
  145. (do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
  146. NS_ENSURE_TRUE(cmdLine, NS_ERROR_FAILURE);
  147. nsresult rv;
  148. rv = cmdLine->Init(0, argv, nullptr,
  149. nsICommandLine::STATE_REMOTE_EXPLICIT);
  150. NS_ENSURE_SUCCESS(rv, rv);
  151. return cmdLine->Run();
  152. }
  153. } // got window mediator
  154. return NS_OK;
  155. NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
  156. }
  157. #pragma mark -
  158. // Create and return an instance of class nsNativeAppSupportCocoa.
  159. nsresult NS_CreateNativeAppSupport(nsINativeAppSupport**aResult)
  160. {
  161. *aResult = new nsNativeAppSupportCocoa;
  162. if (!*aResult) return NS_ERROR_OUT_OF_MEMORY;
  163. NS_ADDREF(*aResult);
  164. return NS_OK;
  165. }