forked from mirrors/gecko-dev
		
	 eafc9e3293
			
		
	
	
		eafc9e3293
		
	
	
	
	
		
			
			nsXULWindow is no longer XUL specific and is somewhat confusing name. Differential Revision: https://phabricator.services.mozilla.com/D51486 --HG-- rename : xpfe/appshell/nsXULWindow.cpp => xpfe/appshell/AppWindow.cpp rename : xpfe/appshell/nsXULWindow.h => xpfe/appshell/AppWindow.h rename : xpfe/appshell/nsIXULWindow.idl => xpfe/appshell/nsIAppWindow.idl extra : moz-landing-system : lando
		
			
				
	
	
		
			119 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| /*
 | |
|  * Windows widget support for event loop instrumentation.
 | |
|  * See toolkit/xre/EventTracer.cpp for more details.
 | |
|  */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <windows.h>
 | |
| 
 | |
| #include "mozilla/RefPtr.h"
 | |
| #include "mozilla/WidgetTraceEvent.h"
 | |
| #include "nsAppShellCID.h"
 | |
| #include "nsComponentManagerUtils.h"
 | |
| #include "nsCOMPtr.h"
 | |
| #include "nsIAppShellService.h"
 | |
| #include "nsIBaseWindow.h"
 | |
| #include "nsIDocShell.h"
 | |
| #include "nsISupportsImpl.h"
 | |
| #include "nsIWidget.h"
 | |
| #include "nsIAppWindow.h"
 | |
| #include "nsServiceManagerUtils.h"
 | |
| #include "nsThreadUtils.h"
 | |
| #include "nsWindowDefs.h"
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| // Used for signaling the background thread from the main thread.
 | |
| HANDLE sEventHandle = nullptr;
 | |
| 
 | |
| // We need a runnable in order to find the hidden window on the main
 | |
| // thread.
 | |
| class HWNDGetter : public mozilla::Runnable {
 | |
|  public:
 | |
|   HWNDGetter() : Runnable("HWNDGetter"), hidden_window_hwnd(nullptr) {}
 | |
| 
 | |
|   HWND hidden_window_hwnd;
 | |
| 
 | |
|   NS_IMETHOD Run() override {
 | |
|     // Jump through some hoops to locate the hidden window.
 | |
|     nsCOMPtr<nsIAppShellService> appShell(
 | |
|         do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
 | |
|     nsCOMPtr<nsIAppWindow> hiddenWindow;
 | |
| 
 | |
|     nsresult rv = appShell->GetHiddenWindow(getter_AddRefs(hiddenWindow));
 | |
|     if (NS_FAILED(rv)) {
 | |
|       return rv;
 | |
|     }
 | |
| 
 | |
|     nsCOMPtr<nsIDocShell> docShell;
 | |
|     rv = hiddenWindow->GetDocShell(getter_AddRefs(docShell));
 | |
|     if (NS_FAILED(rv) || !docShell) {
 | |
|       return rv;
 | |
|     }
 | |
| 
 | |
|     nsCOMPtr<nsIBaseWindow> baseWindow(do_QueryInterface(docShell));
 | |
| 
 | |
|     if (!baseWindow) return NS_ERROR_FAILURE;
 | |
| 
 | |
|     nsCOMPtr<nsIWidget> widget;
 | |
|     baseWindow->GetMainWidget(getter_AddRefs(widget));
 | |
| 
 | |
|     if (!widget) return NS_ERROR_FAILURE;
 | |
| 
 | |
|     hidden_window_hwnd = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW);
 | |
| 
 | |
|     return NS_OK;
 | |
|   }
 | |
| };
 | |
| 
 | |
| HWND GetHiddenWindowHWND() {
 | |
|   // Need to dispatch this to the main thread because plenty of
 | |
|   // the things it wants to access are main-thread-only.
 | |
|   RefPtr<HWNDGetter> getter = new HWNDGetter();
 | |
|   NS_DispatchToMainThread(getter, NS_DISPATCH_SYNC);
 | |
|   return getter->hidden_window_hwnd;
 | |
| }
 | |
| 
 | |
| }  // namespace
 | |
| 
 | |
| namespace mozilla {
 | |
| 
 | |
| bool InitWidgetTracing() {
 | |
|   sEventHandle = CreateEventW(nullptr, FALSE, FALSE, nullptr);
 | |
|   return sEventHandle != nullptr;
 | |
| }
 | |
| 
 | |
| void CleanUpWidgetTracing() {
 | |
|   CloseHandle(sEventHandle);
 | |
|   sEventHandle = nullptr;
 | |
| }
 | |
| 
 | |
| // This function is called from the main (UI) thread.
 | |
| void SignalTracerThread() {
 | |
|   if (sEventHandle != nullptr) SetEvent(sEventHandle);
 | |
| }
 | |
| 
 | |
| // This function is called from the background tracer thread.
 | |
| bool FireAndWaitForTracerEvent() {
 | |
|   MOZ_ASSERT(sEventHandle, "Tracing not initialized!");
 | |
| 
 | |
|   // First, try to find the hidden window.
 | |
|   static HWND hidden_window = nullptr;
 | |
|   if (hidden_window == nullptr) {
 | |
|     hidden_window = GetHiddenWindowHWND();
 | |
|   }
 | |
| 
 | |
|   if (hidden_window == nullptr) return false;
 | |
| 
 | |
|   // Post the tracer message into the hidden window's message queue,
 | |
|   // and then block until it's processed.
 | |
|   PostMessage(hidden_window, MOZ_WM_TRACE, 0, 0);
 | |
|   WaitForSingleObject(sEventHandle, INFINITE);
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| }  // namespace mozilla
 |