Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
michael@0 | 1 | /* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | /* |
michael@0 | 7 | * Runs the main native Cocoa run loop, interrupting it as needed to process |
michael@0 | 8 | * Gecko events. |
michael@0 | 9 | */ |
michael@0 | 10 | |
michael@0 | 11 | #ifndef nsAppShell_h_ |
michael@0 | 12 | #define nsAppShell_h_ |
michael@0 | 13 | |
michael@0 | 14 | class nsCocoaWindow; |
michael@0 | 15 | |
michael@0 | 16 | #include "nsBaseAppShell.h" |
michael@0 | 17 | #include "nsTArray.h" |
michael@0 | 18 | |
michael@0 | 19 | typedef struct _nsCocoaAppModalWindowListItem { |
michael@0 | 20 | _nsCocoaAppModalWindowListItem(NSWindow *aWindow, NSModalSession aSession) : |
michael@0 | 21 | mWindow(aWindow), mSession(aSession), mWidget(nullptr) {} |
michael@0 | 22 | _nsCocoaAppModalWindowListItem(NSWindow *aWindow, nsCocoaWindow *aWidget) : |
michael@0 | 23 | mWindow(aWindow), mSession(nil), mWidget(aWidget) {} |
michael@0 | 24 | NSWindow *mWindow; // Weak |
michael@0 | 25 | NSModalSession mSession; // Weak (not retainable) |
michael@0 | 26 | nsCocoaWindow *mWidget; // Weak |
michael@0 | 27 | } nsCocoaAppModalWindowListItem; |
michael@0 | 28 | |
michael@0 | 29 | class nsCocoaAppModalWindowList { |
michael@0 | 30 | public: |
michael@0 | 31 | nsCocoaAppModalWindowList() {} |
michael@0 | 32 | ~nsCocoaAppModalWindowList() {} |
michael@0 | 33 | // Push a Cocoa app-modal window onto the top of our list. |
michael@0 | 34 | nsresult PushCocoa(NSWindow *aWindow, NSModalSession aSession); |
michael@0 | 35 | // Pop the topmost Cocoa app-modal window off our list. |
michael@0 | 36 | nsresult PopCocoa(NSWindow *aWindow, NSModalSession aSession); |
michael@0 | 37 | // Push a Gecko-modal window onto the top of our list. |
michael@0 | 38 | nsresult PushGecko(NSWindow *aWindow, nsCocoaWindow *aWidget); |
michael@0 | 39 | // Pop the topmost Gecko-modal window off our list. |
michael@0 | 40 | nsresult PopGecko(NSWindow *aWindow, nsCocoaWindow *aWidget); |
michael@0 | 41 | // Return the "session" of the top-most visible Cocoa app-modal window. |
michael@0 | 42 | NSModalSession CurrentSession(); |
michael@0 | 43 | // Has a Gecko modal dialog popped up over a Cocoa app-modal dialog? |
michael@0 | 44 | bool GeckoModalAboveCocoaModal(); |
michael@0 | 45 | private: |
michael@0 | 46 | nsTArray<nsCocoaAppModalWindowListItem> mList; |
michael@0 | 47 | }; |
michael@0 | 48 | |
michael@0 | 49 | // GeckoNSApplication |
michael@0 | 50 | // |
michael@0 | 51 | // Subclass of NSApplication for filtering out certain events. |
michael@0 | 52 | @interface GeckoNSApplication : NSApplication |
michael@0 | 53 | { |
michael@0 | 54 | } |
michael@0 | 55 | @end |
michael@0 | 56 | |
michael@0 | 57 | @class AppShellDelegate; |
michael@0 | 58 | |
michael@0 | 59 | class nsAppShell : public nsBaseAppShell |
michael@0 | 60 | { |
michael@0 | 61 | public: |
michael@0 | 62 | NS_IMETHOD ResumeNative(void); |
michael@0 | 63 | |
michael@0 | 64 | nsAppShell(); |
michael@0 | 65 | |
michael@0 | 66 | nsresult Init(); |
michael@0 | 67 | |
michael@0 | 68 | NS_IMETHOD Run(void); |
michael@0 | 69 | NS_IMETHOD Exit(void); |
michael@0 | 70 | NS_IMETHOD OnProcessNextEvent(nsIThreadInternal *aThread, bool aMayWait, |
michael@0 | 71 | uint32_t aRecursionDepth); |
michael@0 | 72 | NS_IMETHOD AfterProcessNextEvent(nsIThreadInternal *aThread, |
michael@0 | 73 | uint32_t aRecursionDepth, |
michael@0 | 74 | bool aEventWasProcessed); |
michael@0 | 75 | |
michael@0 | 76 | // public only to be visible to Objective-C code that must call it |
michael@0 | 77 | void WillTerminate(); |
michael@0 | 78 | |
michael@0 | 79 | protected: |
michael@0 | 80 | virtual ~nsAppShell(); |
michael@0 | 81 | |
michael@0 | 82 | virtual void ScheduleNativeEventCallback(); |
michael@0 | 83 | virtual bool ProcessNextNativeEvent(bool aMayWait); |
michael@0 | 84 | |
michael@0 | 85 | bool InGeckoMainEventLoop(); |
michael@0 | 86 | |
michael@0 | 87 | static void ProcessGeckoEvents(void* aInfo); |
michael@0 | 88 | |
michael@0 | 89 | protected: |
michael@0 | 90 | CFMutableArrayRef mAutoreleasePools; |
michael@0 | 91 | |
michael@0 | 92 | AppShellDelegate* mDelegate; |
michael@0 | 93 | CFRunLoopRef mCFRunLoop; |
michael@0 | 94 | CFRunLoopSourceRef mCFRunLoopSource; |
michael@0 | 95 | |
michael@0 | 96 | bool mRunningEventLoop; |
michael@0 | 97 | bool mStarted; |
michael@0 | 98 | bool mTerminated; |
michael@0 | 99 | bool mSkippedNativeCallback; |
michael@0 | 100 | bool mRunningCocoaEmbedded; |
michael@0 | 101 | |
michael@0 | 102 | // mHadMoreEventsCount and kHadMoreEventsCountMax are used in |
michael@0 | 103 | // ProcessNextNativeEvent(). |
michael@0 | 104 | uint32_t mHadMoreEventsCount; |
michael@0 | 105 | // Setting kHadMoreEventsCountMax to '10' contributed to a fairly large |
michael@0 | 106 | // (about 10%) increase in the number of calls to malloc (though without |
michael@0 | 107 | // effecting the total amount of memory used). Cutting it to '3' |
michael@0 | 108 | // reduced the number of calls by 6%-7% (reducing the original regression |
michael@0 | 109 | // to 3%-4%). See bmo bug 395397. |
michael@0 | 110 | static const uint32_t kHadMoreEventsCountMax = 3; |
michael@0 | 111 | |
michael@0 | 112 | int32_t mRecursionDepth; |
michael@0 | 113 | int32_t mNativeEventCallbackDepth; |
michael@0 | 114 | // Can be set from different threads, so must be modified atomically |
michael@0 | 115 | int32_t mNativeEventScheduledDepth; |
michael@0 | 116 | }; |
michael@0 | 117 | |
michael@0 | 118 | #endif // nsAppShell_h_ |