Bug 575870 - Enable the firefox button on xp themed, classic, and aero basic. r=dao...
[mozilla-central.git] / toolkit / xre / nsNativeAppSupportCocoa.mm
blob94d55be2f671974562bfeca8e06cbf4666c61a8c
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  * http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  *
15  * The Original Code is Mozilla Communicator client code.
16  *
17  * The Initial Developer of the Original Code is
18  * Netscape Communications Corporation.
19  * Portions created by the Initial Developer are Copyright (C) 1998
20  * the Initial Developer. All Rights Reserved.
21  *
22  * Contributor(s):
23  *   Steven Michaud <smichaud@pobox.com>
24  *
25  * Alternatively, the contents of this file may be used under the terms of
26  * either the GNU General Public License Version 2 or later (the "GPL"), or
27  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28  * in which case the provisions of the GPL or the LGPL are applicable instead
29  * of those above. If you wish to allow use of your version of this file only
30  * under the terms of either the GPL or the LGPL, and not to allow others to
31  * use your version of this file under the terms of the MPL, indicate your
32  * decision by deleting the provisions above and replace them with the notice
33  * and other provisions required by the GPL or the LGPL. If you do not delete
34  * the provisions above, a recipient may use your version of this file under
35  * the terms of any one of the MPL, the GPL or the LGPL.
36  *
37  * ***** END LICENSE BLOCK ***** */
39 #include "nsString.h"
41 #import <CoreServices/CoreServices.h>
42 #import <Cocoa/Cocoa.h>
44 #include "nsCOMPtr.h"
45 #include "nsObjCExceptions.h"
46 #include "nsNativeAppSupportBase.h"
48 #include "nsIAppShellService.h"
49 #include "nsIAppStartup.h"
50 #include "nsIBaseWindow.h"
51 #include "nsICommandLineRunner.h"
52 #include "nsIDOMWindowInternal.h"
53 #include "nsIDocShellTreeItem.h"
54 #include "nsIDocShellTreeOwner.h"
55 #include "nsIInterfaceRequestorUtils.h"
56 #include "nsIObserver.h"
57 #include "nsIServiceManager.h"
58 #include "nsIWebNavigation.h"
59 #include "nsIWidget.h"
60 #include "nsIWindowMediator.h"
62 nsresult
63 GetNativeWindowPointerFromDOMWindow(nsIDOMWindowInternal *a_window, NSWindow **a_nativeWindow)
65   *a_nativeWindow = nil;
66   if (!a_window)
67     return NS_ERROR_INVALID_ARG;
69   nsCOMPtr<nsIWebNavigation> mruWebNav(do_GetInterface(a_window));
70   if (mruWebNav) {
71     nsCOMPtr<nsIDocShellTreeItem> mruTreeItem(do_QueryInterface(mruWebNav));
72     nsCOMPtr<nsIDocShellTreeOwner> mruTreeOwner = nsnull;
73     mruTreeItem->GetTreeOwner(getter_AddRefs(mruTreeOwner));
74     if(mruTreeOwner) {
75       nsCOMPtr<nsIBaseWindow> mruBaseWindow(do_QueryInterface(mruTreeOwner));
76       if (mruBaseWindow) {
77         nsCOMPtr<nsIWidget> mruWidget = nsnull;
78         mruBaseWindow->GetMainWidget(getter_AddRefs(mruWidget));
79         if (mruWidget) {
80           *a_nativeWindow = (NSWindow*)mruWidget->GetNativeData(NS_NATIVE_WINDOW);
81         }
82       }
83     }
84   }
86   return NS_OK;
89 class nsNativeAppSupportCocoa : public nsNativeAppSupportBase
91 public:
92   nsNativeAppSupportCocoa() :
93     mCanShowUI(PR_FALSE) { }
95   NS_IMETHOD Start(PRBool* aRetVal);
96   NS_IMETHOD ReOpen();
97   NS_IMETHOD Enable();
99 private:
100   PRBool mCanShowUI;
104 NS_IMETHODIMP
105 nsNativeAppSupportCocoa::Enable()
107   mCanShowUI = PR_TRUE;
108   return NS_OK;
111 NS_IMETHODIMP nsNativeAppSupportCocoa::Start(PRBool *_retval)
113   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
115   SInt32 response = 0;
116   OSErr err = ::Gestalt (gestaltSystemVersion, &response);
117   response &= 0xFFFF; // The system version is in the low order word
119   // Check that the OS version is supported, if not return PR_FALSE,
120   // which will make the browser quit.  In principle we could display an
121   // alert here.  But the alert's message and buttons would require custom
122   // localization.  So (for now at least) we just log an English message
123   // to the console before quitting.
124 #ifdef __LP64__
125   SInt32 minimumOS = 0x00001060;
126 #else
127   SInt32 minimumOS = 0x00001050;
128 #endif
129   if ((err != noErr) || response < minimumOS) {
130     NSLog(@"Minimum OS version requirement not met!");
131     return PR_FALSE;
132   }
134   *_retval = PR_TRUE;
135   return NS_OK;
137   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
140 NS_IMETHODIMP
141 nsNativeAppSupportCocoa::ReOpen()
143   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
145   if (!mCanShowUI)
146     return NS_ERROR_FAILURE;
148   PRBool haveNonMiniaturized = PR_FALSE;
149   PRBool haveOpenWindows = PR_FALSE;
150   PRBool done = PR_FALSE;
151   
152   nsCOMPtr<nsIWindowMediator> 
153     wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
154   if (!wm) {
155     return NS_ERROR_FAILURE;
156   } 
157   else {
158     nsCOMPtr<nsISimpleEnumerator> windowList;
159     wm->GetXULWindowEnumerator(nsnull, getter_AddRefs(windowList));
160     PRBool more;
161     windowList->HasMoreElements(&more);
162     while (more) {
163       nsCOMPtr<nsISupports> nextWindow = nsnull;
164       windowList->GetNext(getter_AddRefs(nextWindow));
165       nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(nextWindow));
166       if (!baseWindow) {
167         windowList->HasMoreElements(&more);
168         continue;
169       }
170       else {
171         haveOpenWindows = PR_TRUE;
172       }
174       nsCOMPtr<nsIWidget> widget = nsnull;
175       baseWindow->GetMainWidget(getter_AddRefs(widget));
176       if (!widget) {
177         windowList->HasMoreElements(&more);
178         continue;
179       }
180       NSWindow *cocoaWindow = (NSWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
181       if (![cocoaWindow isMiniaturized]) {
182         haveNonMiniaturized = PR_TRUE;
183         break;  //have un-minimized windows, nothing to do
184       } 
185       windowList->HasMoreElements(&more);
186     } // end while
187         
188     if (!haveNonMiniaturized) {
189       // Deminiaturize the most recenty used window
190       nsCOMPtr<nsIDOMWindowInternal> mru = nsnull;
191       wm->GetMostRecentWindow(nsnull, getter_AddRefs(mru));
192             
193       if (mru) {        
194         NSWindow *cocoaMru = nil;
195         GetNativeWindowPointerFromDOMWindow(mru, &cocoaMru);
196         if (cocoaMru) {
197           [cocoaMru deminiaturize:nil];
198           done = PR_TRUE;
199         }
200       }
201       
202     } // end if have non miniaturized
203     
204     if (!haveOpenWindows && !done) {
205       char* argv[] = { nsnull };
206     
207       // use an empty command line to make the right kind(s) of window open
208       nsCOMPtr<nsICommandLineRunner> cmdLine
209         (do_CreateInstance("@mozilla.org/toolkit/command-line;1"));
210       NS_ENSURE_TRUE(cmdLine, NS_ERROR_FAILURE);
212       nsresult rv;
213       rv = cmdLine->Init(0, argv, nsnull,
214                          nsICommandLine::STATE_REMOTE_EXPLICIT);
215       NS_ENSURE_SUCCESS(rv, rv);
217       return cmdLine->Run();
218     }
219     
220   } // got window mediator
221   return NS_OK;
223   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
226 #pragma mark -
228 // Create and return an instance of class nsNativeAppSupportCocoa.
229 nsresult NS_CreateNativeAppSupport(nsINativeAppSupport**aResult)
231   *aResult = new nsNativeAppSupportCocoa;
232   if (!*aResult) return NS_ERROR_OUT_OF_MEMORY;
234   NS_ADDREF(*aResult);
235   return NS_OK;