Fix typo in 9b54bd30006c008b4a951331b273613d5bac3abf
[pm.git] / toolkit / xre / nsNativeAppSupportCocoa.mm
blob1ee8bea5f4f873766b526f7ee3ff95a0b03ace2b
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/. */
6 #include "nsString.h"
8 #import <CoreServices/CoreServices.h>
9 #import <Cocoa/Cocoa.h>
11 #include "nsCOMPtr.h"
12 #include "nsCocoaFeatures.h"
13 #include "nsNativeAppSupportBase.h"
15 #include "nsIAppShellService.h"
16 #include "nsIAppStartup.h"
17 #include "nsIBaseWindow.h"
18 #include "nsICommandLineRunner.h"
19 #include "nsIDOMWindow.h"
20 #include "nsIDocShellTreeItem.h"
21 #include "nsIDocShellTreeOwner.h"
22 #include "nsIInterfaceRequestorUtils.h"
23 #include "nsIObserver.h"
24 #include "nsIServiceManager.h"
25 #include "nsIWebNavigation.h"
26 #include "nsIWidget.h"
27 #include "nsIWindowMediator.h"
29 // This must be included last:
30 #include "nsObjCExceptions.h"
32 nsresult
33 GetNativeWindowPointerFromDOMWindow(nsIDOMWindow *a_window, NSWindow **a_nativeWindow)
35   *a_nativeWindow = nil;
36   if (!a_window)
37     return NS_ERROR_INVALID_ARG;
39   nsCOMPtr<nsIWebNavigation> mruWebNav(do_GetInterface(a_window));
40   if (mruWebNav) {
41     nsCOMPtr<nsIDocShellTreeItem> mruTreeItem(do_QueryInterface(mruWebNav));
42     nsCOMPtr<nsIDocShellTreeOwner> mruTreeOwner = nullptr;
43     mruTreeItem->GetTreeOwner(getter_AddRefs(mruTreeOwner));
44     if(mruTreeOwner) {
45       nsCOMPtr<nsIBaseWindow> mruBaseWindow(do_QueryInterface(mruTreeOwner));
46       if (mruBaseWindow) {
47         nsCOMPtr<nsIWidget> mruWidget = nullptr;
48         mruBaseWindow->GetMainWidget(getter_AddRefs(mruWidget));
49         if (mruWidget) {
50           *a_nativeWindow = (NSWindow*)mruWidget->GetNativeData(NS_NATIVE_WINDOW);
51         }
52       }
53     }
54   }
56   return NS_OK;
59 class nsNativeAppSupportCocoa : public nsNativeAppSupportBase
61 public:
62   nsNativeAppSupportCocoa() :
63     mCanShowUI(false) { }
65   NS_IMETHOD Start(bool* aRetVal);
66   NS_IMETHOD ReOpen();
67   NS_IMETHOD Enable();
69 private:
70   bool mCanShowUI;
73 NS_IMETHODIMP
74 nsNativeAppSupportCocoa::Enable()
76   mCanShowUI = true;
77   return NS_OK;
80 NS_IMETHODIMP nsNativeAppSupportCocoa::Start(bool *_retval)
82   int major, minor, bugfix;
83   nsCocoaFeatures::GetSystemVersion(major, minor, bugfix);
85   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
87   // Check that the OS version is supported, if not return false,
88   // which will make the browser quit.  In principle we could display an
89   // alert here.  But the alert's message and buttons would require custom
90   // localization.  So (for now at least) we just log an English message
91   // to the console before quitting.
92   if (major < 10 || minor < 6) {
93     NSLog(@"Minimum OS version requirement not met!");
94     return NS_OK;
95   }
97   *_retval = true;
98   return NS_OK;
100   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
103 NS_IMETHODIMP
104 nsNativeAppSupportCocoa::ReOpen()
106   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
108   if (!mCanShowUI)
109     return NS_ERROR_FAILURE;
111   bool haveNonMiniaturized = false;
112   bool haveOpenWindows = false;
113   bool done = false;
114   
115   nsCOMPtr<nsIWindowMediator> 
116     wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
117   if (!wm) {
118     return NS_ERROR_FAILURE;
119   } 
120   else {
121     nsCOMPtr<nsISimpleEnumerator> windowList;
122     wm->GetXULWindowEnumerator(nullptr, getter_AddRefs(windowList));
123     bool more;
124     windowList->HasMoreElements(&more);
125     while (more) {
126       nsCOMPtr<nsISupports> nextWindow = nullptr;
127       windowList->GetNext(getter_AddRefs(nextWindow));
128       nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(nextWindow));
129       if (!baseWindow) {
130         windowList->HasMoreElements(&more);
131         continue;
132       }
133       else {
134         haveOpenWindows = true;
135       }
137       nsCOMPtr<nsIWidget> widget = nullptr;
138       baseWindow->GetMainWidget(getter_AddRefs(widget));
139       if (!widget) {
140         windowList->HasMoreElements(&more);
141         continue;
142       }
143       NSWindow *cocoaWindow = (NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
144       if (![cocoaWindow isMiniaturized]) {
145         haveNonMiniaturized = true;
146         break;  //have un-minimized windows, nothing to do
147       } 
148       windowList->HasMoreElements(&more);
149     } // end while
150         
151     if (!haveNonMiniaturized) {
152       // Deminiaturize the most recenty used window
153       nsCOMPtr<nsIDOMWindow> mru;
154       wm->GetMostRecentWindow(nullptr, getter_AddRefs(mru));
155             
156       if (mru) {        
157         NSWindow *cocoaMru = nil;
158         GetNativeWindowPointerFromDOMWindow(mru, &cocoaMru);
159         if (cocoaMru) {
160           [cocoaMru deminiaturize:nil];
161           done = true;
162         }
163       }
164       
165     } // end if have non miniaturized
166     
167     if (!haveOpenWindows && !done) {
168       char* argv[] = { nullptr };
169     
170       // use an empty command line to make the right kind(s) of window open
171       nsCOMPtr<nsICommandLineRunner> cmdLine
172         (do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
173       NS_ENSURE_TRUE(cmdLine, NS_ERROR_FAILURE);
175       nsresult rv;
176       rv = cmdLine->Init(0, argv, nullptr,
177                          nsICommandLine::STATE_REMOTE_EXPLICIT);
178       NS_ENSURE_SUCCESS(rv, rv);
180       return cmdLine->Run();
181     }
182     
183   } // got window mediator
184   return NS_OK;
186   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
189 #pragma mark -
191 // Create and return an instance of class nsNativeAppSupportCocoa.
192 nsresult NS_CreateNativeAppSupport(nsINativeAppSupport**aResult)
194   *aResult = new nsNativeAppSupportCocoa;
195   if (!*aResult) return NS_ERROR_OUT_OF_MEMORY;
197   NS_ADDREF(*aResult);
198   return NS_OK;