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/. */
8 #import <CoreServices/CoreServices.h>
9 #import <Cocoa/Cocoa.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"
33 GetNativeWindowPointerFromDOMWindow(nsIDOMWindow *a_window, NSWindow **a_nativeWindow)
35 *a_nativeWindow = nil;
37 return NS_ERROR_INVALID_ARG;
39 nsCOMPtr<nsIWebNavigation> mruWebNav(do_GetInterface(a_window));
41 nsCOMPtr<nsIDocShellTreeItem> mruTreeItem(do_QueryInterface(mruWebNav));
42 nsCOMPtr<nsIDocShellTreeOwner> mruTreeOwner = nullptr;
43 mruTreeItem->GetTreeOwner(getter_AddRefs(mruTreeOwner));
45 nsCOMPtr<nsIBaseWindow> mruBaseWindow(do_QueryInterface(mruTreeOwner));
47 nsCOMPtr<nsIWidget> mruWidget = nullptr;
48 mruBaseWindow->GetMainWidget(getter_AddRefs(mruWidget));
50 *a_nativeWindow = (NSWindow*)mruWidget->GetNativeData(NS_NATIVE_WINDOW);
59 class nsNativeAppSupportCocoa : public nsNativeAppSupportBase
62 nsNativeAppSupportCocoa() :
65 NS_IMETHOD Start(bool* aRetVal);
74 nsNativeAppSupportCocoa::Enable()
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!");
100 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
104 nsNativeAppSupportCocoa::ReOpen()
106 NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
109 return NS_ERROR_FAILURE;
111 bool haveNonMiniaturized = false;
112 bool haveOpenWindows = false;
115 nsCOMPtr<nsIWindowMediator>
116 wm(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
118 return NS_ERROR_FAILURE;
121 nsCOMPtr<nsISimpleEnumerator> windowList;
122 wm->GetXULWindowEnumerator(nullptr, getter_AddRefs(windowList));
124 windowList->HasMoreElements(&more);
126 nsCOMPtr<nsISupports> nextWindow = nullptr;
127 windowList->GetNext(getter_AddRefs(nextWindow));
128 nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(nextWindow));
130 windowList->HasMoreElements(&more);
134 haveOpenWindows = true;
137 nsCOMPtr<nsIWidget> widget = nullptr;
138 baseWindow->GetMainWidget(getter_AddRefs(widget));
140 windowList->HasMoreElements(&more);
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
148 windowList->HasMoreElements(&more);
151 if (!haveNonMiniaturized) {
152 // Deminiaturize the most recenty used window
153 nsCOMPtr<nsIDOMWindow> mru;
154 wm->GetMostRecentWindow(nullptr, getter_AddRefs(mru));
157 NSWindow *cocoaMru = nil;
158 GetNativeWindowPointerFromDOMWindow(mru, &cocoaMru);
160 [cocoaMru deminiaturize:nil];
165 } // end if have non miniaturized
167 if (!haveOpenWindows && !done) {
168 char* argv[] = { nullptr };
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);
176 rv = cmdLine->Init(0, argv, nullptr,
177 nsICommandLine::STATE_REMOTE_EXPLICIT);
178 NS_ENSURE_SUCCESS(rv, rv);
180 return cmdLine->Run();
183 } // got window mediator
186 NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
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;