From 87cf0f67a653df05774b253e0d867176dbaea2dc Mon Sep 17 00:00:00 2001 From: "pinkerton%netscape.com" Date: Wed, 4 Apr 2001 21:42:42 +0000 Subject: [PATCH] new borderless wdef to bring in line with win32 windows. clean up mdef code to be in line with wdef code. git-svn-id: svn://10.0.0.236/trunk@91336 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/widget/src/mac/nsMacWindow.cpp | 155 ++++++++++++++++++++++--- 1 file changed, 142 insertions(+), 13 deletions(-) diff --git a/mozilla/widget/src/mac/nsMacWindow.cpp b/mozilla/widget/src/mac/nsMacWindow.cpp index 25c573c9751..2dc8a5bf741 100644 --- a/mozilla/widget/src/mac/nsMacWindow.cpp +++ b/mozilla/widget/src/mac/nsMacWindow.cpp @@ -35,6 +35,8 @@ #include "nsGUIEvent.h" #include "nsCarbonHelpers.h" #include "nsGFXUtils.h" +#include "DefProcFakery.h" +#include "nsMacResources.h" #include @@ -51,6 +53,11 @@ static const char *sScreenManagerContractID = "@mozilla.org/gfx/screenmanager;1" #endif +#if !TARGET_CARBON +pascal long BorderlessWDEF ( short inCode, WindowPtr inWindow, short inMessage, long inParam ) ; +long CallSystemWDEF ( short inCode, WindowPtr inWindow, short inMessage, long inParam ) ; +#endif + // These magic adjustments are so that the contained webshells hangs one pixel // off the right and bottom sides of the window. This aligns the scroll bar // correctly, and compensates for different window frame dimentions on @@ -293,6 +300,10 @@ nsMacWindow::~nsMacWindow() { if (mWindowPtr) { + // cleanup our special defproc if we are a popup + if ( mWindowType == eWindowType_popup ) + RemoveBorderlessDefProc ( mWindowPtr ); + // cleanup the struct we hang off the scrollbar's refcon if ( mPhantomScrollbar ) { ::SetControlReference(mPhantomScrollbar, (long)nsnull); @@ -360,18 +371,19 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, switch (mWindowType) { case eWindowType_popup: - // (pinkerton) - // Added very very early support for |eBorderStyle_BorderlessTopLevel| - // and sets mAcceptsActivation to false so we don't activate the window - // when we show it. - // - // ...fall through... - mOffsetParent = aParent; - if(aParent != nsnull){ - theToolkit = getter_AddRefs(aParent->GetToolkit()); - } + // We're a popup, context menu, etc. Sets + // mAcceptsActivation to false so we don't activate the window + // when we show it. + mOffsetParent = aParent; + if( !aParent ) + theToolkit = getter_AddRefs(aParent->GetToolkit()); - mAcceptsActivation = PR_FALSE; + mAcceptsActivation = PR_FALSE; + goAwayFlag = false; + hOffset = 0; + vOffset = 0; + wDefProcID = plainDBox; + break; case eWindowType_child: wDefProcID = plainDBox; @@ -507,7 +519,7 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, if (mWindowPtr == nsnull) return NS_ERROR_OUT_OF_MEMORY; - + nsMacMessageSink::AddRaptorWindowToList(mWindowPtr, this); // create the root control @@ -554,6 +566,11 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, NS_ASSERTION ( result == noErr, "can't install drag receive handler"); } + // If we're a popup, we don't want a border (we want CSS to draw it for us). So + // install our own window defProc. + if ( mWindowType == eWindowType_popup ) + InstallBorderlessDefProc(mWindowPtr); + return NS_OK; } @@ -575,6 +592,47 @@ NS_IMETHODIMP nsMacWindow::Create(nsNativeWidget aNativeParent, // this is a wi aNativeParent)); } + +// +// InstallBorderlessDefProc +// +// For xul popups, we want borderless windows to match win32's borderless windows. Stash +// our fake WDEF into this window which takes care of not-drawing the borders. +// +void +nsMacWindow :: InstallBorderlessDefProc ( WindowPtr inWindow ) +{ +#if !TARGET_CARBON + // stash the real WDEF so we can call it later + Handle systemPopupWDEF = ((WindowPeek)inWindow)->windowDefProc; + + // load the stub WDEF and stash it away. If this fails, we'll just use the normal one. + WindowDefUPP wdef = NewWindowDefUPP( BorderlessWDEF ); + Handle fakedDefProc; + DefProcFakery::CreateDefProc ( wdef, systemPopupWDEF, &fakedDefProc ); + if ( fakedDefProc ) + ((WindowPeek)inWindow)->windowDefProc = fakedDefProc; +#endif +} // InstallBorderlessDefProc + + +// +// RemoveBorderlessDefProc +// +// Clean up the mess we've made with our fake defproc. Reset it to +// the system one, just in case someone needs it around after we're +// through with it. +// +void +nsMacWindow :: RemoveBorderlessDefProc ( WindowPtr inWindow ) +{ + Handle fakedProc = ((WindowPeek)inWindow)->windowDefProc; + Handle oldProc = DefProcFakery::GetSystemDefProc(fakedProc); + DefProcFakery::DestroyDefProc ( fakedProc ); + ((WindowPeek)inWindow)->windowDefProc = oldProc; +} + + //------------------------------------------------------------------------- // // Hide or show this window @@ -1057,4 +1115,75 @@ void nsMacWindow::SetIsActive(PRBool aActive) void nsMacWindow::IsActive(PRBool* aActive) { *aActive = mIsActive; -} \ No newline at end of file +} + + +#if !TARGET_CARBON + +// needed for CallWindowDefProc() to work correctly +#pragma options align=mac68k + + +// +// BorderlessWDEF +// +// The window defproc for borderless windows. +// +// NOTE: Assumes the window was created with a variant of |plainDBox| so our +// content/structure adjustments work correctly. +// +pascal long +BorderlessWDEF ( short inCode, WindowPtr inWindow, short inMessage, long inParam ) +{ + switch ( inMessage ) { + case kWindowMsgDraw: + case kWindowMsgDrawGrowOutline: + case kWindowMsgGetFeatures: + break; + + case kWindowMsgCalculateShape: + // Make the content area bigger so that it draws over the structure region. Use + // the sytem wdef to compute the struct/content regions and then play. + long result = CallSystemWDEF(inCode, inWindow, inMessage, inParam); + ::InsetRgn(((WindowPeek)inWindow)->contRgn, -1, -1); + + // for some reason, the topleft corner doesn't draw correctly unless i do this. + Rect& structRect = (**((WindowPeek)inWindow)->strucRgn).rgnBBox; + structRect.top++; structRect.left++; + break; + + default: + return CallSystemWDEF(inCode, inWindow, inMessage, inParam); + break; + } + + return 0; +} + + +// +// CallSystemWDEF +// +// We really don't want to reinvent the wheel, so call back into the system wdef we have +// stashed away. +// +long +CallSystemWDEF ( short inCode, WindowPtr inWindow, short inMessage, long inParam ) +{ + // extract the real system wdef out of the fake one we've stored in the window + Handle fakedWDEF = ((WindowPeek)inWindow)->windowDefProc; + Handle systemDefProc = DefProcFakery::GetSystemDefProc ( fakedWDEF ); + + SInt8 state = ::HGetState(systemDefProc); + ::HLock(systemDefProc); + + long retval = CallWindowDefProc( (RoutineDescriptorPtr)*systemDefProc, inCode, inWindow, inMessage, inParam); + + ::HSetState(systemDefProc, state); + + return retval; +} + +#pragma options align=reset + +#endif