mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 161623 - Mac embedding APIs are burdensome compared to other platforms because the embeddor must create a top level nsIWidget instead of passing a native one. r=pink/sr=sfraser
This commit is contained in:
parent
5d58c9449f
commit
4de2ea650f
@ -68,6 +68,10 @@ EXTRA_DSO_LDOPTS= \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifeq (mac,$(MOZ_WIDGET_TOOLKIT))
|
||||
EXTRA_DSO_LDOPTS += $(TK_LIBS)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -64,7 +64,6 @@
|
||||
#include "nsIHistoryEntry.h"
|
||||
#include "nsISHEntry.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
#include "nsIMacTextInputEventSink.h"
|
||||
#include "nsCRT.h"
|
||||
@ -340,57 +339,6 @@ NS_IMETHODIMP CBrowserShell::CommonConstruct()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* It is a necessary evil to create a top level window widget in order to
|
||||
* have a parent for our nsIBaseWindow. In order to not put that responsibility
|
||||
* onto the PowerPlant window which contains us, we do it ourselves here by
|
||||
* creating the widget if it does not exist and storing it as a window property.
|
||||
*/
|
||||
|
||||
NS_IMETHODIMP CBrowserShell::EnsureTopLevelWidget(nsIWidget **aWidget)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aWidget);
|
||||
*aWidget = nsnull;
|
||||
|
||||
OSStatus err;
|
||||
nsresult rv;
|
||||
nsIWidget *widget = nsnull;
|
||||
|
||||
err = ::GetWindowProperty(GetMacWindow(), 'PPMZ', 'WIDG', sizeof(nsIWidget*), nsnull, (void*)&widget);
|
||||
if (err == noErr && widget) {
|
||||
*aWidget = widget;
|
||||
NS_ADDREF(*aWidget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Create it with huge bounds. The actual bounds that matters is that of the
|
||||
// nsIBaseWindow. The bounds of the top level widget clips its children so
|
||||
// we just have to make sure it is big enough to always contain the children.
|
||||
// Under 10.2, if this rect is too large, subwidget offsets can temporarily push the
|
||||
// bounds over 32,727 and OffsetRgn() will silently fail. In order to avoid that, we
|
||||
// err towards a local max of the size of the gray rgn.
|
||||
|
||||
nsCOMPtr<nsIWidget> newWidget(do_CreateInstance(kWindowCID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RgnHandle grayRgn = ::GetGrayRgn();
|
||||
Rect grayRect;
|
||||
::GetRegionBounds(grayRgn, &grayRect);
|
||||
nsRect r(0, 0, grayRect.right - grayRect.left, grayRect.bottom - grayRect.top);
|
||||
rv = newWidget->Create(GetMacWindow(), r, nsnull, nsnull, nsnull, nsnull, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
widget = newWidget;
|
||||
err = ::SetWindowProperty(GetMacWindow(), 'PPMZ', 'WIDG', sizeof(nsIWidget*), (void*)&widget);
|
||||
if (err == noErr) {
|
||||
*aWidget = newWidget;
|
||||
NS_ADDREF(*aWidget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//*** CBrowserShell: LPane overrides
|
||||
@ -399,14 +347,6 @@ NS_IMETHODIMP CBrowserShell::EnsureTopLevelWidget(nsIWidget **aWidget)
|
||||
void CBrowserShell::FinishCreateSelf()
|
||||
{
|
||||
FocusDraw();
|
||||
|
||||
nsCOMPtr<nsIWidget> aWidget;
|
||||
ThrowIfError_(EnsureTopLevelWidget(getter_AddRefs(aWidget)));
|
||||
|
||||
// the widget is also our avenue for dispatching events into Gecko via
|
||||
// nsIEventSink. Save this sink for later.
|
||||
mEventSink = do_QueryInterface(aWidget);
|
||||
ThrowIfNil_(mEventSink);
|
||||
|
||||
Rect portFrame;
|
||||
CalcPortFrameRect(portFrame);
|
||||
@ -414,8 +354,10 @@ void CBrowserShell::FinishCreateSelf()
|
||||
|
||||
nsresult rv;
|
||||
|
||||
mWebBrowserAsBaseWin->InitWindow(aWidget->GetNativeData(NS_NATIVE_WIDGET), nsnull, r.x, r.y, r.width, r.height);
|
||||
mWebBrowserAsBaseWin->InitWindow(GetMacWindow(), nsnull, r.x, r.y, r.width, r.height);
|
||||
mWebBrowserAsBaseWin->Create();
|
||||
mEventSink = do_GetInterface(mWebBrowser);
|
||||
ThrowIfNil_(mEventSink);
|
||||
|
||||
// Hook up our progress listener
|
||||
nsWeakPtr weakling(dont_AddRef(NS_GetWeakReference((nsIWebProgressListener *)mProgressListener)));
|
||||
@ -938,18 +880,6 @@ NS_METHOD CBrowserShell::SetWebBrowser(nsIWebBrowser* aBrowser)
|
||||
|
||||
FocusDraw();
|
||||
|
||||
/*
|
||||
CBrowserWindow *ourWindow = dynamic_cast<CBrowserWindow*>(LWindow::FetchWindowObject(GetMacWindow()));
|
||||
NS_ENSURE_TRUE(ourWindow, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIWidget> aWidget;
|
||||
ourWindow->GetWidget(getter_AddRefs(aWidget));
|
||||
NS_ENSURE_TRUE(aWidget, NS_ERROR_FAILURE);
|
||||
*/
|
||||
|
||||
nsCOMPtr<nsIWidget> aWidget;
|
||||
ThrowIfError_(EnsureTopLevelWidget(getter_AddRefs(aWidget)));
|
||||
|
||||
mWebBrowser = aBrowser;
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mWebBrowser));
|
||||
@ -964,8 +894,10 @@ NS_METHOD CBrowserShell::SetWebBrowser(nsIWebBrowser* aBrowser)
|
||||
CalcPortFrameRect(portFrame);
|
||||
nsRect r(portFrame.left, portFrame.top, portFrame.right - portFrame.left, portFrame.bottom - portFrame.top);
|
||||
|
||||
mWebBrowserAsBaseWin->InitWindow(aWidget->GetNativeData(NS_NATIVE_WIDGET), nsnull, r.x, r.y, r.width, r.height);
|
||||
mWebBrowserAsBaseWin->InitWindow(GetMacWindow(), nsnull, r.x, r.y, r.width, r.height);
|
||||
mWebBrowserAsBaseWin->Create();
|
||||
mEventSink = do_GetInterface(mWebBrowser);
|
||||
ThrowIfNil_(mEventSink);
|
||||
|
||||
AdjustFrame();
|
||||
|
||||
|
@ -195,7 +195,6 @@ protected:
|
||||
|
||||
|
||||
NS_METHOD CommonConstruct();
|
||||
NS_METHOD EnsureTopLevelWidget(nsIWidget **aWidget);
|
||||
|
||||
void HandleMouseMoved(const EventRecord& inMacEvent);
|
||||
void AdjustFrame();
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
|
||||
#include "CBrowserWindow.h"
|
||||
@ -172,21 +171,6 @@ void CBrowserWindow::FinishCreateSelf()
|
||||
StartBroadcasting();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ¥ ShowSelf
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void CBrowserWindow::ShowSelf()
|
||||
{
|
||||
Inherited::ShowSelf();
|
||||
|
||||
nsIWidget *widget = nsnull;
|
||||
|
||||
OSStatus err = ::GetWindowProperty(GetMacWindow(), 'PPMZ', 'WIDG', sizeof(nsIWidget*), nsnull, (void*)&widget);
|
||||
if (err == noErr && widget)
|
||||
widget->Show(PR_TRUE);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ¥ ListenToMessage
|
||||
|
@ -60,8 +60,6 @@ public:
|
||||
|
||||
virtual void FinishCreateSelf();
|
||||
|
||||
virtual void ShowSelf();
|
||||
|
||||
virtual void ListenToMessage(MessageT inMessage,
|
||||
void* ioParam);
|
||||
|
||||
|
@ -71,7 +71,14 @@
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#endif
|
||||
|
||||
#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
|
||||
#include <MacWindows.h>
|
||||
#include "nsWidgetSupport.h"
|
||||
#include "nsIEventSink.h"
|
||||
#endif
|
||||
|
||||
static NS_DEFINE_CID(kWebShellCID, NS_WEB_SHELL_CID);
|
||||
static NS_DEFINE_IID(kWindowCID, NS_WINDOW_CID);
|
||||
static NS_DEFINE_CID(kChildCID, NS_CHILD_CID);
|
||||
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
||||
|
||||
@ -93,6 +100,9 @@ nsWebBrowser::nsWebBrowser() : mDocShellTreeOwner(nsnull),
|
||||
mParentWidget(nsnull),
|
||||
mParent(nsnull),
|
||||
mListenerArray(nsnull)
|
||||
#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
|
||||
, mTopLevelWidget(nsnull)
|
||||
#endif
|
||||
{
|
||||
mInitInfo = new nsWebBrowserInitInfo();
|
||||
mWWatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
|
||||
@ -135,6 +145,10 @@ NS_IMETHODIMP nsWebBrowser::InternalDestroy()
|
||||
mListenerArray = nsnull;
|
||||
}
|
||||
|
||||
#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
|
||||
NS_IF_RELEASE(mTopLevelWidget);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -173,6 +187,11 @@ NS_IMETHODIMP nsWebBrowser::GetInterface(const nsIID& aIID, void** aSink)
|
||||
if(NS_SUCCEEDED(QueryInterface(aIID, aSink)))
|
||||
return NS_OK;
|
||||
|
||||
#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
|
||||
if (aIID.Equals(NS_GET_IID(nsIEventSink)) && mTopLevelWidget)
|
||||
return mTopLevelWidget->QueryInterface(NS_GET_IID(nsIEventSink), aSink);
|
||||
#endif
|
||||
|
||||
if (mDocShell) {
|
||||
if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
|
||||
nsCOMPtr<nsIContentViewer> viewer;
|
||||
@ -331,6 +350,40 @@ NS_IMETHODIMP nsWebBrowser::EnableGlobalHistory(PRBool aEnable)
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
|
||||
NS_IMETHODIMP nsWebBrowser::EnsureTopLevelWidget(nativeWindow aWindow)
|
||||
{
|
||||
WindowPtr macWindow = NS_STATIC_CAST(WindowPtr, aWindow);
|
||||
nsIWidget *widget = nsnull;
|
||||
nsCOMPtr<nsIWidget> newWidget;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
::GetWindowProperty(macWindow, kTopLevelWidgetPropertyCreator,
|
||||
kTopLevelWidgetRefPropertyTag, sizeof(nsIWidget*), nsnull, (void*)&widget);
|
||||
if (!widget) {
|
||||
newWidget = do_CreateInstance(kWindowCID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
||||
// Create it with huge bounds. The actual bounds that matters is that of the
|
||||
// nsIBaseWindow. The bounds of the top level widget clips its children so
|
||||
// we just have to make sure it is big enough to always contain the children.
|
||||
|
||||
nsRect r(0, 0, 32000, 32000);
|
||||
rv = newWidget->Create(macWindow, r, nsnull, nsnull, nsnull, nsnull, nsnull);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
widget = newWidget;
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(widget, "Failed to get or create a toplevel widget!!");
|
||||
if (widget) {
|
||||
mTopLevelWidget = widget;
|
||||
NS_ADDREF(mTopLevelWidget); // Allows multiple nsWebBrowsers to be in 1 window.
|
||||
rv = NS_OK;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP nsWebBrowser::GetContainerWindow(nsIWebBrowserChrome** aTopWindow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTopWindow);
|
||||
@ -1292,8 +1345,14 @@ NS_IMETHODIMP nsWebBrowser::GetParentNativeWindow(nativeWindow* aParentNativeWin
|
||||
NS_IMETHODIMP nsWebBrowser::SetParentNativeWindow(nativeWindow aParentNativeWindow)
|
||||
{
|
||||
NS_ENSURE_STATE(!mDocShell);
|
||||
|
||||
|
||||
#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
|
||||
nsresult rv = EnsureTopLevelWidget(aParentNativeWindow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mParentNativeWindow = mTopLevelWidget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
#else
|
||||
mParentNativeWindow = aParentNativeWindow;
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -158,7 +158,13 @@ protected:
|
||||
nsIWidget* mParentWidget;
|
||||
nsIDocShellTreeItem* mParent;
|
||||
nsVoidArray * mListenerArray;
|
||||
|
||||
|
||||
#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
|
||||
NS_IMETHOD EnsureTopLevelWidget(nativeWindow aWindow);
|
||||
|
||||
nsIWidget* mTopLevelWidget;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* nsWebBrowser_h__ */
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "nsRegionMac.h"
|
||||
#include "nsIRollupListener.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsWidgetSupport.h"
|
||||
|
||||
#if TARGET_CARBON
|
||||
#include <CFString.h>
|
||||
@ -253,7 +254,10 @@ nsMacWindow::~nsMacWindow()
|
||||
if (mustResetPort)
|
||||
nsGraphicsUtils::SetPortToKnownGoodPort();
|
||||
}
|
||||
|
||||
else if ( mWindowPtr && !mWindowMadeHere ) {
|
||||
(void)::RemoveWindowProperty(mWindowPtr, kTopLevelWidgetPropertyCreator,
|
||||
kTopLevelWidgetRefPropertyTag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -478,6 +482,7 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent,
|
||||
{
|
||||
mWindowPtr = (WindowPtr)aNativeParent;
|
||||
mWindowMadeHere = PR_FALSE;
|
||||
mVisible = PR_TRUE;
|
||||
}
|
||||
|
||||
if (mWindowPtr == nsnull)
|
||||
@ -488,7 +493,9 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent,
|
||||
// event handlers to get our widget or event sink when all they have
|
||||
// is a native WindowPtr.
|
||||
nsIWidget* temp = NS_STATIC_CAST(nsIWidget*, this);
|
||||
OSStatus swpStatus = ::SetWindowProperty ( mWindowPtr, 'MOSS', 'GEKO', sizeof(nsIWidget*), &temp );
|
||||
OSStatus swpStatus = ::SetWindowProperty ( mWindowPtr,
|
||||
kTopLevelWidgetPropertyCreator, kTopLevelWidgetRefPropertyTag,
|
||||
sizeof(nsIWidget*), &temp );
|
||||
NS_ASSERTION ( swpStatus == noErr, "couldn't set a property on the window, event handling will fail" );
|
||||
if ( swpStatus != noErr )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "nsIWidget.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsWidgetAtoms.h"
|
||||
#include "nsWidgetSupport.h"
|
||||
|
||||
#include <Gestalt.h>
|
||||
#include <Appearance.h>
|
||||
@ -390,7 +391,9 @@ void
|
||||
nsToolkit::GetTopWidget ( WindowPtr aWindow, nsIWidget** outWidget )
|
||||
{
|
||||
nsIWidget* topLevelWidget = nsnull;
|
||||
::GetWindowProperty ( aWindow, 'MOSS', 'GEKO', sizeof(nsIWidget*), nsnull, (void*)&topLevelWidget);
|
||||
::GetWindowProperty ( aWindow,
|
||||
kTopLevelWidgetPropertyCreator, kTopLevelWidgetRefPropertyTag,
|
||||
sizeof(nsIWidget*), nsnull, (void*)&topLevelWidget);
|
||||
if ( topLevelWidget ) {
|
||||
*outWidget = topLevelWidget;
|
||||
NS_ADDREF(*outWidget);
|
||||
|
@ -56,6 +56,16 @@ class nsICheckButton;
|
||||
class nsITooltipWidget;
|
||||
class nsITextWidget;
|
||||
|
||||
#if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
|
||||
// A top-level widget stores a reference to itself as a window property
|
||||
// with the following creator and tag. These constants are used by embedding
|
||||
// code in addition to widget code.
|
||||
enum {
|
||||
kTopLevelWidgetPropertyCreator = 'MOSS',
|
||||
kTopLevelWidgetRefPropertyTag = 'GEKO'
|
||||
};
|
||||
#endif
|
||||
|
||||
// These are a series of support methods which help in the creation
|
||||
// of widgets. They are not needed, but are provided as a convenience
|
||||
// mechanism when creating widgets
|
||||
|
Loading…
Reference in New Issue
Block a user