michael@0: /* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * Runs the main native Cocoa run loop, interrupting it as needed to process michael@0: * Gecko events. michael@0: */ michael@0: michael@0: #ifndef nsAppShell_h_ michael@0: #define nsAppShell_h_ michael@0: michael@0: class nsCocoaWindow; michael@0: michael@0: #include "nsBaseAppShell.h" michael@0: #include "nsTArray.h" michael@0: michael@0: typedef struct _nsCocoaAppModalWindowListItem { michael@0: _nsCocoaAppModalWindowListItem(NSWindow *aWindow, NSModalSession aSession) : michael@0: mWindow(aWindow), mSession(aSession), mWidget(nullptr) {} michael@0: _nsCocoaAppModalWindowListItem(NSWindow *aWindow, nsCocoaWindow *aWidget) : michael@0: mWindow(aWindow), mSession(nil), mWidget(aWidget) {} michael@0: NSWindow *mWindow; // Weak michael@0: NSModalSession mSession; // Weak (not retainable) michael@0: nsCocoaWindow *mWidget; // Weak michael@0: } nsCocoaAppModalWindowListItem; michael@0: michael@0: class nsCocoaAppModalWindowList { michael@0: public: michael@0: nsCocoaAppModalWindowList() {} michael@0: ~nsCocoaAppModalWindowList() {} michael@0: // Push a Cocoa app-modal window onto the top of our list. michael@0: nsresult PushCocoa(NSWindow *aWindow, NSModalSession aSession); michael@0: // Pop the topmost Cocoa app-modal window off our list. michael@0: nsresult PopCocoa(NSWindow *aWindow, NSModalSession aSession); michael@0: // Push a Gecko-modal window onto the top of our list. michael@0: nsresult PushGecko(NSWindow *aWindow, nsCocoaWindow *aWidget); michael@0: // Pop the topmost Gecko-modal window off our list. michael@0: nsresult PopGecko(NSWindow *aWindow, nsCocoaWindow *aWidget); michael@0: // Return the "session" of the top-most visible Cocoa app-modal window. michael@0: NSModalSession CurrentSession(); michael@0: // Has a Gecko modal dialog popped up over a Cocoa app-modal dialog? michael@0: bool GeckoModalAboveCocoaModal(); michael@0: private: michael@0: nsTArray mList; michael@0: }; michael@0: michael@0: // GeckoNSApplication michael@0: // michael@0: // Subclass of NSApplication for filtering out certain events. michael@0: @interface GeckoNSApplication : NSApplication michael@0: { michael@0: } michael@0: @end michael@0: michael@0: @class AppShellDelegate; michael@0: michael@0: class nsAppShell : public nsBaseAppShell michael@0: { michael@0: public: michael@0: NS_IMETHOD ResumeNative(void); michael@0: michael@0: nsAppShell(); michael@0: michael@0: nsresult Init(); michael@0: michael@0: NS_IMETHOD Run(void); michael@0: NS_IMETHOD Exit(void); michael@0: NS_IMETHOD OnProcessNextEvent(nsIThreadInternal *aThread, bool aMayWait, michael@0: uint32_t aRecursionDepth); michael@0: NS_IMETHOD AfterProcessNextEvent(nsIThreadInternal *aThread, michael@0: uint32_t aRecursionDepth, michael@0: bool aEventWasProcessed); michael@0: michael@0: // public only to be visible to Objective-C code that must call it michael@0: void WillTerminate(); michael@0: michael@0: protected: michael@0: virtual ~nsAppShell(); michael@0: michael@0: virtual void ScheduleNativeEventCallback(); michael@0: virtual bool ProcessNextNativeEvent(bool aMayWait); michael@0: michael@0: bool InGeckoMainEventLoop(); michael@0: michael@0: static void ProcessGeckoEvents(void* aInfo); michael@0: michael@0: protected: michael@0: CFMutableArrayRef mAutoreleasePools; michael@0: michael@0: AppShellDelegate* mDelegate; michael@0: CFRunLoopRef mCFRunLoop; michael@0: CFRunLoopSourceRef mCFRunLoopSource; michael@0: michael@0: bool mRunningEventLoop; michael@0: bool mStarted; michael@0: bool mTerminated; michael@0: bool mSkippedNativeCallback; michael@0: bool mRunningCocoaEmbedded; michael@0: michael@0: // mHadMoreEventsCount and kHadMoreEventsCountMax are used in michael@0: // ProcessNextNativeEvent(). michael@0: uint32_t mHadMoreEventsCount; michael@0: // Setting kHadMoreEventsCountMax to '10' contributed to a fairly large michael@0: // (about 10%) increase in the number of calls to malloc (though without michael@0: // effecting the total amount of memory used). Cutting it to '3' michael@0: // reduced the number of calls by 6%-7% (reducing the original regression michael@0: // to 3%-4%). See bmo bug 395397. michael@0: static const uint32_t kHadMoreEventsCountMax = 3; michael@0: michael@0: int32_t mRecursionDepth; michael@0: int32_t mNativeEventCallbackDepth; michael@0: // Can be set from different threads, so must be modified atomically michael@0: int32_t mNativeEventScheduledDepth; michael@0: }; michael@0: michael@0: #endif // nsAppShell_h_