From d71235b9a69f2395ddfc859910b900adff9050c5 Mon Sep 17 00:00:00 2001 From: "pinkerton%netscape.com" Date: Thu, 29 Nov 2001 14:38:56 +0000 Subject: [PATCH] removing nsMacMessageSink for standalone and embedding. Replacing with nsIEventSink and a couple of internal interfaces. r=ccarlen/sr=sfraser. bug#110851 --- embedding/browser/powerplant/PPBrowser.mcp | Bin 278606 -> 278606 bytes .../powerplant/source/CBrowserShell.cpp | 31 +- .../browser/powerplant/source/CBrowserShell.h | 6 +- .../browser/powerplant/source/CThrobber.cpp | 2 +- .../powerplant/source/EmbedEventHandling.cpp | 96 +- .../powerplant/source/EmbedEventHandling.h | 10 +- widget/macbuild/WidgetSupport.mcp | Bin 117154 -> 117154 bytes widget/macbuild/WidgetSupportConfig.h | 4 - widget/macbuild/widgetIDL.mcp | Bin 69738 -> 71370 bytes widget/public/Makefile.in | 4 + widget/public/nsIEventSink.idl | 40 +- widget/src/mac/Makefile.in | 3 +- widget/src/mac/nsAppShell.cpp | 5 +- widget/src/mac/nsAppShell.h | 2 - widget/src/mac/nsFilePicker.cpp | 18 +- widget/src/mac/nsMacEventHandler.cpp | 7 + widget/src/mac/nsMacMessagePump.cpp | 70 +- widget/src/mac/nsMacMessagePump.h | 7 +- widget/src/mac/nsMacWindow.cpp | 1165 +++++++++-------- widget/src/mac/nsMacWindow.h | 25 +- widget/src/mac/nsPIEventSinkStandalone.idl | 49 + widget/src/mac/nsPIWidgetMac.idl | 43 + widget/src/mac/nsToolkit.cpp | 43 +- widget/src/mac/nsToolkit.h | 9 + 24 files changed, 976 insertions(+), 663 deletions(-) create mode 100644 widget/src/mac/nsPIEventSinkStandalone.idl create mode 100644 widget/src/mac/nsPIWidgetMac.idl diff --git a/embedding/browser/powerplant/PPBrowser.mcp b/embedding/browser/powerplant/PPBrowser.mcp index f36d11efabc3e3c36d4a4ce58a04bcda98739f70..211095b7aad271ccde7804039fa4ec652ce29b5c 100755 GIT binary patch delta 450 zcmX@tAb74paKkAscCCV728P-j(+e&!i)?<%RWF*t&%h|?=IP@KqVynovFils1|yq!<~= z&%p2)B)|lvfqYgdA4~)Jp-?`U2J+dUd@v2P&K+_ zP}&tr2SVwu5Smd3O6x<#zd`vnP}&Vd18sE&)02IbR2cau7b&^20L6kP?^cSIVE_Sn y9=~7(pUkA9#G=g9VxRysNIm;xD;5384byp=bCuh3l^KDU35c1u=PI*2lmP%f7hpI5 delta 450 zcmX@tAb74paKkAscEO!`3=C0@(+e&!i)?<%RWF*t$G|A)=IP@KqiN3ljsQ*W}$w(K7hl fIoV1@e{#cgp5|QT_FQE~AZ7w$=Iy!4EDvP>r-)zA diff --git a/embedding/browser/powerplant/source/CBrowserShell.cpp b/embedding/browser/powerplant/source/CBrowserShell.cpp index ccf3ebe4e4fb..0ad0dea81989 100644 --- a/embedding/browser/powerplant/source/CBrowserShell.cpp +++ b/embedding/browser/powerplant/source/CBrowserShell.cpp @@ -79,9 +79,6 @@ static NS_DEFINE_IID(kWindowCID, NS_WINDOW_CID); -// CBrowserShell static variables -nsMacMessageSink CBrowserShell::mMessageSink; - //***************************************************************************** //*** CBrowserShell: constructors/destructor @@ -156,6 +153,11 @@ void CBrowserShell::FinishCreateSelf() nsCOMPtr aWidget; ourWindow->GetWidget(getter_AddRefs(aWidget)); ThrowIfNil_(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); @@ -209,7 +211,8 @@ void CBrowserShell::DrawSelf() { EventRecord osEvent; osEvent.what = updateEvt; - mMessageSink.DispatchOSEvent(osEvent, Compat_GetMacWindow()); + PRBool handled = PR_FALSE; + mEventSink->DispatchEvent(&osEvent, &handled); } @@ -219,14 +222,16 @@ void CBrowserShell::ClickSelf(const SMouseDownEvent &inMouseDown) SwitchTarget(this); FocusDraw(); - mMessageSink.DispatchOSEvent((EventRecord&)inMouseDown.macEvent, Compat_GetMacWindow()); + PRBool handled = PR_FALSE; + mEventSink->DispatchEvent(&const_cast(inMouseDown.macEvent), &handled); } void CBrowserShell::EventMouseUp(const EventRecord &inMacEvent) { FocusDraw(); - mMessageSink.DispatchOSEvent((EventRecord&)inMacEvent, Compat_GetMacWindow()); + PRBool handled = PR_FALSE; + mEventSink->DispatchEvent(&const_cast(inMacEvent), &handled); LEventDispatcher *dispatcher = LEventDispatcher::GetCurrentEventDispatcher(); if (dispatcher) @@ -288,7 +293,8 @@ Boolean CBrowserShell::HandleKeyPress(const EventRecord &inKeyEvent) FocusDraw(); // dispatch the event - Boolean keyHandled = mMessageSink.DispatchOSEvent((EventRecord&)inKeyEvent, Compat_GetMacWindow()); + PRBool handled = PR_FALSE; + Boolean keyHandled = mEventSink->DispatchEvent(&const_cast(inKeyEvent), &handled); return keyHandled; } @@ -466,12 +472,14 @@ void CBrowserShell::SpendTime(const EventRecord& inMacEvent) { case osEvt: { - // The MacMessageSink will not set the cursor if we are in the background - which is right. + // The event sink will not set the cursor if we are in the background - which is right. // We have to feed it suspendResumeMessages for it to know unsigned char eventType = ((inMacEvent.message >> 24) & 0x00ff); - if (eventType == suspendResumeMessage) - mMessageSink.DispatchOSEvent(const_cast(inMacEvent), Compat_GetMacWindow()); + if (eventType == suspendResumeMessage) { + PRBool handled = PR_FALSE; + mEventSink->DispatchEvent(&const_cast(inMacEvent), &handled); + } } break; } @@ -872,7 +880,8 @@ void CBrowserShell::HandleMouseMoved(const EventRecord& inMacEvent) if (IsActive()) { FocusDraw(); - mMessageSink.DispatchOSEvent(const_cast(inMacEvent), Compat_GetMacWindow()); + PRBool handled = PR_FALSE; + mEventSink->DispatchEvent(&const_cast(inMacEvent), &handled); } } diff --git a/embedding/browser/powerplant/source/CBrowserShell.h b/embedding/browser/powerplant/source/CBrowserShell.h index 349fa067e4e8..6757586e29fd 100644 --- a/embedding/browser/powerplant/source/CBrowserShell.h +++ b/embedding/browser/powerplant/source/CBrowserShell.h @@ -33,6 +33,7 @@ #include "nsIBaseWindow.h" #include "nsIWebNavigation.h" #include "nsIWidget.h" +#include "nsIEventSink.h" #include "nsMacMessageSink.h" #include "nsIDocShellTreeItem.h" #include "nsIWebProgress.h" @@ -162,11 +163,10 @@ protected: Boolean HasFormElements(); -protected: - static nsMacMessageSink mMessageSink; - +protected: LStr255 mInitURL; + nsCOMPtr mEventSink; // for event dispatch nsCOMPtr mWebBrowser; // The thing we actually create nsCOMPtr mWebBrowserAsBaseWin; // Convenience interface to above nsCOMPtr mWebBrowserAsWebNav; // Ditto diff --git a/embedding/browser/powerplant/source/CThrobber.cpp b/embedding/browser/powerplant/source/CThrobber.cpp index 941ff668125f..13f7d03fd85f 100644 --- a/embedding/browser/powerplant/source/CThrobber.cpp +++ b/embedding/browser/powerplant/source/CThrobber.cpp @@ -163,7 +163,7 @@ void CThrobber::DrawSelf() { #if 0 // Draw directly with the rendering context instead of passing an - // update event through nsMacMessageSink. By the time this routine is + // update event through event sink. By the time this routine is // called, PowerPlant has taken care of the location, z order, and clipping // of each view. Since focusing puts the the origin at our top left corner, // all we have to do is get the bounds of the widget and put that at (0,0) diff --git a/embedding/browser/powerplant/source/EmbedEventHandling.cpp b/embedding/browser/powerplant/source/EmbedEventHandling.cpp index 5933c9ffe008..7789cd8cb3c7 100644 --- a/embedding/browser/powerplant/source/EmbedEventHandling.cpp +++ b/embedding/browser/powerplant/source/EmbedEventHandling.cpp @@ -26,9 +26,12 @@ #include "prthread.h" #include "SIOUX.h" +#include "nsIWidget.h" +#include "nsIEventSink.h" +#include "nsCOMPtr.h" + // Static Variables -nsMacMessageSink CEmbedEventAttachment::mMessageSink; WindowPtr CEmbedEventAttachment::mLastAlienWindowClicked; //***************************************************************************** @@ -46,6 +49,46 @@ CEmbedEventAttachment::~CEmbedEventAttachment() { } + +// +// GetTopWidget +// +// We've stashed the nsIWidget for the given windowPtr in the data +// properties of the window. Fetch it. +// +void +CEmbedEventAttachment::GetTopWidget ( WindowPtr aWindow, nsIWidget** outWidget ) +{ + nsIWidget* topLevelWidget = nsnull; + ::GetWindowProperty ( aWindow, 'MOSS', 'GEKO', sizeof(nsIWidget*), nsnull, (void*)&topLevelWidget); + if ( topLevelWidget ) { + *outWidget = topLevelWidget; + NS_ADDREF(*outWidget); + } +} + + +// +// GetWindowEventSink +// +// We've stashed the nsIEventSink for the given windowPtr in the data of the +// root control. Fetch it. +// +void +CEmbedEventAttachment::GetWindowEventSink ( WindowPtr aWindow, nsIEventSink** outSink ) +{ + *outSink = nsnull; + + nsCOMPtr topWidget; + GetTopWidget ( aWindow, getter_AddRefs(topWidget) ); + nsCOMPtr sink ( do_QueryInterface(topWidget) ); + if ( sink ) { + *outSink = sink; + NS_ADDREF(*outSink); + } +} + + void CEmbedEventAttachment::ExecuteSelf(MessageT inMessage, void* ioParam) { @@ -65,8 +108,13 @@ void CEmbedEventAttachment::ExecuteSelf(MessageT inMessage, inMacEvent = static_cast(ioParam); ::MacFindWindow(inMacEvent->where, &macWindowP); if (IsAlienGeckoWindow(macWindowP)) { - mMessageSink.DispatchOSEvent(*inMacEvent, macWindowP); - SetExecuteHost(false); + nsCOMPtr sink; + GetWindowEventSink(macWindowP, getter_AddRefs(sink)); + if ( sink ) { + PRBool handled = PR_FALSE; + sink->DispatchEvent(inMacEvent, &handled); + SetExecuteHost(false); + } } } else if (inMessage == msg_Event) { @@ -97,9 +145,14 @@ void CEmbedEventAttachment::ExecuteSelf(MessageT inMessage, { SInt16 thePart = ::MacFindWindow(inMacEvent->where, &macWindowP); if (thePart == inContent && IsAlienGeckoWindow(macWindowP)) { - mMessageSink.DispatchOSEvent(*inMacEvent, macWindowP); - mLastAlienWindowClicked = macWindowP; - SetExecuteHost(false); + nsCOMPtr sink; + GetWindowEventSink(macWindowP, getter_AddRefs(sink)); + if ( sink ) { + PRBool handled = PR_FALSE; + sink->DispatchEvent(inMacEvent, &handled); + mLastAlienWindowClicked = macWindowP; + SetExecuteHost(false); + } } else mLastAlienWindowClicked = nil; @@ -109,9 +162,14 @@ void CEmbedEventAttachment::ExecuteSelf(MessageT inMessage, case mouseUp: { if (mLastAlienWindowClicked) { - mMessageSink.DispatchOSEvent(*inMacEvent, mLastAlienWindowClicked); + nsCOMPtr sink; + GetWindowEventSink(mLastAlienWindowClicked, getter_AddRefs(sink)); + if ( sink ) { + PRBool handled = PR_FALSE; + sink->DispatchEvent(inMacEvent, &handled); mLastAlienWindowClicked = nil; SetExecuteHost(false); + } } } break; @@ -119,10 +177,15 @@ void CEmbedEventAttachment::ExecuteSelf(MessageT inMessage, case updateEvt: case activateEvt: { - macWindowP = (WindowPtr)inMacEvent->message; + macWindowP = (WindowPtr)inMacEvent->message; if (IsAlienGeckoWindow(macWindowP)) { - mMessageSink.DispatchOSEvent(*inMacEvent, macWindowP); + nsCOMPtr sink; + GetWindowEventSink(macWindowP, getter_AddRefs(sink)); + if ( sink ) { + PRBool handled = PR_FALSE; + sink->DispatchEvent(inMacEvent, &handled); SetExecuteHost(false); + } } } break; @@ -133,9 +196,18 @@ void CEmbedEventAttachment::ExecuteSelf(MessageT inMessage, Boolean CEmbedEventAttachment::IsAlienGeckoWindow(WindowPtr inMacWindow) { - return (inMacWindow && - !LWindow::FetchWindowObject(inMacWindow) && - mMessageSink.IsRaptorWindow(inMacWindow)); + PRBool isAlien = PR_FALSE; + + // it's an 'alien' window if there's no LWindow object and there is + // an nsIEventSink stashed in the window's root control. + if (inMacWindow && !LWindow::FetchWindowObject(inMacWindow)) { + nsCOMPtr sink; + GetWindowEventSink ( inMacWindow, getter_AddRefs(sink) ); + if ( sink ) + isAlien = PR_TRUE; + } + + return isAlien; } diff --git a/embedding/browser/powerplant/source/EmbedEventHandling.h b/embedding/browser/powerplant/source/EmbedEventHandling.h index 744c6752b892..a8056124d63c 100644 --- a/embedding/browser/powerplant/source/EmbedEventHandling.h +++ b/embedding/browser/powerplant/source/EmbedEventHandling.h @@ -26,7 +26,9 @@ #include "LAttachment.h" #include "LPeriodical.h" -#include "nsMacMessageSink.h" +class nsIWidget; +class nsIEventSink; + //***************************************************************************** // class CEmbedEventAttachment @@ -51,7 +53,11 @@ public: protected: Boolean IsAlienGeckoWindow(WindowPtr inMacWindow); - static nsMacMessageSink mMessageSink; + // utility routines for getting the toplevel widget and event sink + // stashed in the properties of gecko windows. + static void GetWindowEventSink ( WindowPtr aWindow, nsIEventSink** outSink ) ; + static void GetTopWidget ( WindowPtr aWindow, nsIWidget** outWidget ) ; + static WindowPtr mLastAlienWindowClicked; }; diff --git a/widget/macbuild/WidgetSupport.mcp b/widget/macbuild/WidgetSupport.mcp index 8a533bd2341fe1dec96965d22a9e7e3a5ca6e764..8bdd58647604cc4b98c398ea759a3440636cf876 100644 GIT binary patch delta 270 zcmZ29nSIe@_6^32oa_t?3`{`GG1-ApdU7~pfFLK3C(j5ZfOr{@;@rH0k(+7qF=qM6 zFPSwM7j5Qd>0{(%a`W_Y1*%vuc@^t5BZiqXXA;E5#>US1d1;yHdKpT*n^&=IV`JAk zQ1$=+xw6gayypejHC^`o|9|lE=Elxw*UNvMr40ONBcB#FL gNsLUbcc$0vV-#n6J$>3fMt#=jV5w947;kU^0Hg+8k^lez delta 250 zcmZ29nSIe@_6^32yc`S+4D3M61jL+^Z5X8|M>F~easherj6ed2mjNlR%{v&mnI<1# zR$^Q@`98DuWb7p6K`0M5*v2}6E!)(%=-7iH!>&VG9-=Tb z!JxoGJ;KR`5&?q?Z*mPTK2RYM8G)2U42lm-5Mi2ukYI?B`JH>mKw{#boO}NN|Nirz z|8-CQyZXNUdS`Qcdx#LCBZTG2R@s*9ebH0Q_oJP z6tOpQtg({34i^9~#RqFVwjfpmA^H=9n7~4AY6;DsKRFzkxhxuO50_Pgga<0Ruyf)n3PpZYQ(I76*k7Ea6GQcT}v{&Gy>L#a-$>*vG3Vt*)%Bh1D>*Sfy)oT3K*T zsjwZ|vxoNaMQo()ajgTnSdu%yN}bs(eN!tL>5D@*YvjM$0+uWa@M_E^{io;>po&>GV>a zNu&(Z+3cD(%a9GOT;Py1XSEt!WKE?{8fYBH>6?@F}&c za~qq7HN!SF(Z=wC#!!2>g%!T;RpL9okz!Rrbu6d5lBn}P8;01s;$&G@Tr|v(3^65E zTqs&*Lb=tJDQl(}sf{3MF)5-*l43A?7N>G4usD@nJ<-GlNAyt>%IT&GtNq<6 zi&p8>eCTK9^s8I-sB*6EavR-I1S{oZKfy`iL% zQqXHQ#HtL+shhGv=^KbkYIRW`F+yG;=?u*03p&8Ml=v z@s%Z1`MmxzRgSM-pTU1K(4bV9z$Yb8zhsH?g$cBPR`IRaf^j%;v_+S+V!v;+WikD= zZP8HszxB3@kaOB1QP}IQfFB~?W87|}Bcz?Hc(#%HC)%3;q%T?8vXJO|y1{2@hOKMx z{4CM*uk=7SR@1*Qz+c0;^rR@lFlu=2Ibh;%0d1?`XW&15`(pf&4h=tg9e{Y^K=zmU z9f8|7LojRjtO?+A1q!^I`%N@8ZMWbxxcOu7qJ|*XWL_`e55UjRU>T8+0s-R04c=)& zb|Yr+-6nceN`8qiOr&L!O!$FB91|~+cB$^q%iyPrLxd#%z<*4{v6N%{mM~Ag%4e7n zWIkSS$*Nt`vK@xARCAJ&%EM;i_HBN|jAHyUO^iF569SIz-zCR0{EnHXW|*M3+q?VW z@1d{#aH54)OBE@V5VS^Qti1_dQ~>n;s^LatT$?Kts+yc}<0o{gv1R;`0i9?PXrPau zu_4v1!~MxPr-Ocvijsr<{EiK&eT@kn>W`A7r{NN!UE-lr z!5`ABWDoCzl~jF@AGO0<&5O9rtp&3|1S$FhS}E}XffsZ@@N4)A2L6aZ3Hj<(?va6K z&WDhr;hmGgi-$Sb#_V%uKSMOS&+7{ZoRuIotC`iGhpeY53O46bPVzISIPf;Va zB#Jd+Pj? zoR_MNJ9Dw7km7|=#1ihr{m>U-tR}?LMMx%8)0Q)tXTAxEu4#D;s<~K$f-zl9rI_S) z1#GWt6?-xFaYo$*>|~*j4M!qu)ZW9|9kbYBM{lY=(+9G|fnm=5*X(7JlRIBv8)63A z?#&YA)t4zd>#1cg#iBZ)lr?)FWy_p(soL2r;4P7bp;9EnkSTA7y z$I{8kH{TUgs;^PD>jUK>Bh~s94xYn@#+Bc&aX*$w3uoJqfL*CN=BbizT}Yb$Jfr`Q;&+stAl#2Mz-^$ah)I|BX+bYV&JywxX(Pd$Gy_OHZUr*I9=1Uzkq5YNSZ#!sIb0_$a zgT`n+zl3S=Zq(puO>St$e9QfC?uVUdO}4cC$A1xaNo#u&@%k^&Z;0nOf67VyT4@d6 z>ZH*-?cV?hZP>VW9kKMj1AUqbtjHiF<6-6B(hFaa@;7(zb66L$r$NJ}@ENCo6)Svp zBagbMKh(AZUz|tb1AhRMpAy7zfj3IrX@!xk@CB97)%7M$H}7`QykHevE(Ndo6nZ%Z z#CL@cNH_s~u7cf3=rIXm#a2Fn-L>*|p5dkgnrkN?a??ec>k@Z)uq+!fDye??9P~MI z5g~4a&-GxL|2kjkLAW>0dtiqe9>BeEs5EPP5V*h$C&qnzM8^5z+@FKPm>9<0CTNcQ zXPIBDit`Tg#vGa#&WHI=?{0ysUV%T+zaxh>Xm!SV7^)HBPT9P@7?9m{HyaWD9el_> z(@oyr1HWN%3ttGsCz}Kr3Gk?aQaf(;Cwxl&kv=q0(!Pf`8Ypew$2a>ES$-7Q0fpxs z=iLU4(ilHx&_EEkfT$!9S`EEVMS0ip2}Ehn4)TZ(yKUNrYym~)bxHCg6}RFM{-DGI zA=pucZ(`7qUCRC;-XZbGc^D-M?~X&4j3ALde#nPnUWTsvHuDFZ2l+&T_$|Bn_i}kb z6AX1*X03P&`eza)PR_TRUE if event was handled + * PR_FALSE if not handled + * + * On Mac, anEvent is a native EventRecord*. + */ + boolean dispatchEvent ( in voidPtr anEvent ) ; - boolean DispatchEvent ( in voidPtr anEvent, in voidPtr aNativeChild ) ; + /** + * Alerts gecko of a drag event. + * + * @param aMessage the message parameter for a Gecko NS_DRAGDROP_EVENT (See nsGUIEvent.h for list). + * @param aMouseGlobalX x coordinate of mouse, in global coordinates + * @param aMouseGlobalY y coordinate of mouse, in global coordinates + * @param aKeyModifiers a native bitfield of which modifier keys are currently pressed + * + * @return PR_TRUE if event was handled + * PR_FALSE if not handled + */ + boolean dragEvent ( in unsigned long aMessage, in short aMouseGlobalX, in short aMouseGlobalY, + in unsigned short aKeyModifiers ) ; + + /** + * Perform any idle processing (handle timers, set the cursor, etc) + */ + void Idle ( ) ; }; \ No newline at end of file diff --git a/widget/src/mac/Makefile.in b/widget/src/mac/Makefile.in index dd313aca3d0d..9d5702765489 100644 --- a/widget/src/mac/Makefile.in +++ b/widget/src/mac/Makefile.in @@ -68,7 +68,6 @@ CPPSRCS = nsAppShell.cpp \ nsMacControl.cpp \ nsMacEventHandler.cpp \ nsMacMessagePump.cpp \ - nsMacMessageSink.cpp \ nsMacResources.cpp \ nsMacTSMMessagePump.cpp \ nsMacWindow.cpp \ @@ -90,6 +89,8 @@ CPPSRCS = nsAppShell.cpp \ XPIDLSRCS += \ nsIChangeManager.idl \ nsIMenuCommandDispatcher.idl \ + nsPIWidgetMac.idl \ + nsPIEventSinkStandalone.idl \ $(NULL) GARBAGE += $(GFX_LCPPSRCS) diff --git a/widget/src/mac/nsAppShell.cpp b/widget/src/mac/nsAppShell.cpp index acec707b3fbf..0d5e8237a08b 100644 --- a/widget/src/mac/nsAppShell.cpp +++ b/widget/src/mac/nsAppShell.cpp @@ -98,12 +98,11 @@ NS_IMETHODIMP nsAppShell::Create(int* argc, char ** argv) rv = NS_GetCurrentToolkit(getter_AddRefs(mToolkit)); if (NS_FAILED(rv)) return rv; - mMacSink.reset(new nsMacMessageSink()); nsIToolkit* toolkit = mToolkit.get(); - mMacPump.reset(new nsMacMessagePump(static_cast(toolkit), mMacSink.get())); + mMacPump.reset(new nsMacMessagePump(static_cast(toolkit))); mMacMemoryCushion.reset(new nsMacMemoryCushion()); - if (!mMacSink.get() || !mMacPump.get() || !mMacMemoryCushion.get()) + if (!mMacPump.get() || !mMacMemoryCushion.get()) return NS_ERROR_OUT_OF_MEMORY; OSErr err = mMacMemoryCushion->Init(nsMacMemoryCushion::kMemoryBufferSize, nsMacMemoryCushion::kMemoryReserveSize); diff --git a/widget/src/mac/nsAppShell.h b/widget/src/mac/nsAppShell.h index a3a3b5702131..b806fc7eb75f 100644 --- a/widget/src/mac/nsAppShell.h +++ b/widget/src/mac/nsAppShell.h @@ -56,7 +56,6 @@ using std::auto_ptr; class nsMacMessagePump; -class nsMacMessageSink; class nsMacMemoryCushion; @@ -73,7 +72,6 @@ class nsAppShell : public nsIAppShell nsDispatchListener *mDispatchListener; // note: we don't own this, but it can be NULL nsCOMPtr mToolkit; auto_ptr mMacPump; - auto_ptr mMacSink; // this will be COM, so use scc's COM_auto_ptr auto_ptr mMacMemoryCushion; PRBool mExitCalled; static PRBool mInitializedToolbox; diff --git a/widget/src/mac/nsFilePicker.cpp b/widget/src/mac/nsFilePicker.cpp index 2b7e0d8e6cf0..4045891a1d99 100644 --- a/widget/src/mac/nsFilePicker.cpp +++ b/widget/src/mac/nsFilePicker.cpp @@ -32,6 +32,8 @@ #include "nsIURL.h" #include "nsVoidArray.h" #include "nsIFileChannel.h" +#include "nsToolkit.h" +#include "nsIEventSink.h" #include @@ -39,8 +41,6 @@ #include "nsCarbonHelpers.h" #include "nsFilePicker.h" -#include "nsMacWindow.h" -#include "nsMacMessageSink.h" #include "nsWatchTask.h" #include "nsIInternetConfigService.h" @@ -169,6 +169,7 @@ NS_IMETHODIMP nsFilePicker::Show(PRInt16 *retval) } + // // FileDialogEventHandlerProc // @@ -181,13 +182,14 @@ static pascal void FileDialogEventHandlerProc( NavEventCallbackMessage msg, NavC switch ( cbRec->eventData.eventDataParms.event->what ) { case updateEvt: WindowPtr window = reinterpret_cast(cbRec->eventData.eventDataParms.event->message); - nsMacWindow* macWindow = nsMacMessageSink::GetNSWindowFromMacWindow(window); - ::BeginUpdate(window); - if (macWindow) { - EventRecord theEvent = *cbRec->eventData.eventDataParms.event; - macWindow->HandleOSEvent(theEvent); + nsCOMPtr sink; + nsToolkit::GetWindowEventSink ( window, getter_AddRefs(sink) ); + if ( sink ) { + ::BeginUpdate(window); + PRBool handled = PR_FALSE; + sink->DispatchEvent(cbRec->eventData.eventDataParms.event, &handled); + ::EndUpdate(window); } - ::EndUpdate(window); break; } break; diff --git a/widget/src/mac/nsMacEventHandler.cpp b/widget/src/mac/nsMacEventHandler.cpp index a808589e0441..ee16daf9474a 100644 --- a/widget/src/mac/nsMacEventHandler.cpp +++ b/widget/src/mac/nsMacEventHandler.cpp @@ -1522,6 +1522,13 @@ PRBool nsMacEventHandler::HandleMouseDownEvent(EventRecord& aOSEvent) mTopLevelWidget->Resize(macRect.right - macRect.left, macRect.bottom - macRect.top, PR_FALSE); break; } + +#if TARGET_CARBON + case inToolbarButton: // rjc: Mac OS X + gEventDispatchHandler.DispatchGuiEvent(mTopLevelWidget, NS_XUL_CLOSE); + break; +#endif + } return retVal; } diff --git a/widget/src/mac/nsMacMessagePump.cpp b/widget/src/mac/nsMacMessagePump.cpp index 4df1500324c6..76bf026f5a8f 100644 --- a/widget/src/mac/nsMacMessagePump.cpp +++ b/widget/src/mac/nsMacMessagePump.cpp @@ -51,7 +51,6 @@ // #include "nsMacMessagePump.h" -#include "nsMacMessageSink.h" #include "nsWidgetsCID.h" #include "nsToolkit.h" #include "nscore.h" @@ -79,6 +78,9 @@ #include "nsCarbonHelpers.h" #include "nsWatchTask.h" +#include "nsIEventSink.h" +#include "nsPIWidgetMac.h" +#include "nsPIEventSinkStandalone.h" #include "nsISocketTransportService.h" #include "nsIFileTransportService.h" @@ -195,8 +197,8 @@ static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); * @param aToolkit -- The toolkit created by the application * @return NONE */ -nsMacMessagePump::nsMacMessagePump(nsToolkit *aToolkit, nsMacMessageSink* aSink) - : mToolkit(aToolkit), mMessageSink(aSink), mTSMMessagePump(NULL) +nsMacMessagePump::nsMacMessagePump(nsToolkit *aToolkit) + : mToolkit(aToolkit), mTSMMessagePump(NULL) { mRunning = PR_FALSE; mMouseRgn = ::NewRgn(); @@ -560,9 +562,11 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent) if ( IsWindowHilited(whichWindow) || (gRollupListener && gRollupWidget) ) DispatchOSEventToRaptor(anEvent, whichWindow); else { - nsMacWindow *mw = mMessageSink->GetNSWindowFromMacWindow(whichWindow); - if (mw) - mw->ComeToFront(); + nsCOMPtr topWidget; + nsToolkit::GetTopWidget ( whichWindow, getter_AddRefs(topWidget) ); + nsCOMPtr macWindow ( do_QueryInterface(topWidget) ); + if ( macWindow ) + macWindow->ComeToFront(); } break; } @@ -589,9 +593,11 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent) // only activate if the command key is not down if (!(anEvent.modifiers & cmdKey)) { - nsMacWindow *mw = mMessageSink->GetNSWindowFromMacWindow(whichWindow); - if (mw) - mw->ComeToFront(); + nsCOMPtr topWidget; + nsToolkit::GetTopWidget ( whichWindow, getter_AddRefs(topWidget) ); + nsCOMPtr macWindow ( do_QueryInterface(topWidget) ); + if ( macWindow ) + macWindow->ComeToFront(); } // Dispatch the event because some windows may want to know that they have been moved. @@ -707,11 +713,12 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent) if (partCode == inZoomOut) { - nsMacWindow *whichMacWindow = nsMacMessageSink::GetNSWindowFromMacWindow(whichWindow); - if (whichMacWindow) - whichMacWindow->CalculateAndSetZoomedSize(); - } - + nsCOMPtr topWidget; + nsToolkit::GetTopWidget ( whichWindow, getter_AddRefs(topWidget) ); + nsCOMPtr macWindow ( do_QueryInterface(topWidget) ); + if ( macWindow ) + macWindow->CalculateAndSetZoomedSize(); + } // !!! Do not call ZoomWindow before calling DispatchOSEventToRaptor // otherwise nsMacEventHandler::HandleMouseDownEvent won't get // the right partcode for the click location @@ -722,15 +729,12 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent) break; #if TARGET_CARBON - case inToolbarButton: // rjc: Mac OS X - nsWatchTask::GetTask().Suspend(); - nsMacWindow *mw = mMessageSink->GetNSWindowFromMacWindow(whichWindow); - if (mw) - { - gEventDispatchHandler.DispatchGuiEvent(mw, NS_OS_TOOLBAR); - } - nsWatchTask::GetTask().Resume(); - break; + case inToolbarButton: // rjc: Mac OS X + nsWatchTask::GetTask().Suspend(); + ::SetPortWindowPort(whichWindow); + DispatchOSEventToRaptor(anEvent, whichWindow); + nsWatchTask::GetTask().Resume(); + break; #endif } @@ -937,6 +941,9 @@ void nsMacMessagePump::DoIdle(EventRecord &anEvent) #pragma mark - + + + //------------------------------------------------------------------------- // // DispatchOSEventToRaptor @@ -946,9 +953,12 @@ PRBool nsMacMessagePump::DispatchOSEventToRaptor( EventRecord &anEvent, WindowPtr aWindow) { - if (mMessageSink->IsRaptorWindow(aWindow)) - return mMessageSink->DispatchOSEvent(anEvent, aWindow); - return PR_FALSE; + PRBool handled = PR_FALSE; + nsCOMPtr sink; + nsToolkit::GetWindowEventSink ( aWindow, getter_AddRefs(sink) ); + if ( sink ) + sink->DispatchEvent ( &anEvent, &handled ); + return handled; } @@ -967,9 +977,11 @@ PRBool nsMacMessagePump::DispatchMenuCommandToRaptor( PRBool handled = PR_FALSE; WindowPtr theFrontWindow = GetFrontApplicationWindow(); - if (mMessageSink->IsRaptorWindow(theFrontWindow)) - handled = mMessageSink->DispatchMenuCommand(anEvent, menuResult, theFrontWindow); - + nsCOMPtr sink; + nsToolkit::GetWindowEventSink ( theFrontWindow, getter_AddRefs(sink) ); + nsCOMPtr menuSink ( do_QueryInterface(sink) ); + if ( menuSink ) + menuSink->DispatchMenuEvent ( &anEvent, menuResult, &handled ); return handled; } diff --git a/widget/src/mac/nsMacMessagePump.h b/widget/src/mac/nsMacMessagePump.h index b9f6c880da9a..26bf17c7297e 100644 --- a/widget/src/mac/nsMacMessagePump.h +++ b/widget/src/mac/nsMacMessagePump.h @@ -59,9 +59,9 @@ #include "nsIEventQueueService.h" class nsToolkit; -class nsMacMessageSink; class nsMacTSMMessagePump; - +class nsIEventSink; +class nsIWidget; //================================================ @@ -75,13 +75,12 @@ private: Point mMousePoint; // keep track of where the mouse is at all times RgnHandle mMouseRgn; nsToolkit* mToolkit; - nsMacMessageSink* mMessageSink; nsMacTSMMessagePump* mTSMMessagePump; // CLASS METHODS public: - nsMacMessagePump(nsToolkit *aToolKit, nsMacMessageSink* aSink); + nsMacMessagePump(nsToolkit *aToolKit); virtual ~nsMacMessagePump(); void DoMessagePump(); diff --git a/widget/src/mac/nsMacWindow.cpp b/widget/src/mac/nsMacWindow.cpp index 713cc07134c2..64a551d5ad1d 100644 --- a/widget/src/mac/nsMacWindow.cpp +++ b/widget/src/mac/nsMacWindow.cpp @@ -37,8 +37,8 @@ #include "nsMacWindow.h" #include "nsMacEventHandler.h" -#include "nsMacMessageSink.h" #include "nsMacControl.h" +#include "nsToolkit.h" #include "nsIServiceManager.h" // for drag and drop #include "nsWidgetsCID.h" @@ -75,10 +75,10 @@ static const char *sScreenManagerContractID = "@mozilla.org/gfx/screenmanager;1" // from MacHeaders.c #ifndef topLeft - #define topLeft(r) (((Point *) &(r))[0]) + #define topLeft(r) (((Point *) &(r))[0]) #endif #ifndef botRight - #define botRight(r) (((Point *) &(r))[1]) + #define botRight(r) (((Point *) &(r))[1]) #endif // externs defined in nsWindow.cpp @@ -113,21 +113,21 @@ void SetDragActionBasedOnModifiers ( nsIDragService* inDragService, short inModi void SetDragActionBasedOnModifiers ( nsIDragService* inDragService, short inModifiers ) { - nsCOMPtr dragSession; - inDragService->GetCurrentSession ( getter_AddRefs(dragSession) ); - if ( dragSession ) { - PRUint32 action = nsIDragService::DRAGDROP_ACTION_MOVE; - - // force copy = option, alias = cmd-option, default is move - if ( inModifiers & optionKey ) { - if ( inModifiers & cmdKey ) - action = nsIDragService::DRAGDROP_ACTION_LINK; - else - action = nsIDragService::DRAGDROP_ACTION_COPY; - } + nsCOMPtr dragSession; + inDragService->GetCurrentSession ( getter_AddRefs(dragSession) ); + if ( dragSession ) { + PRUint32 action = nsIDragService::DRAGDROP_ACTION_MOVE; + + // force copy = option, alias = cmd-option, default is move + if ( inModifiers & optionKey ) { + if ( inModifiers & cmdKey ) + action = nsIDragService::DRAGDROP_ACTION_LINK; + else + action = nsIDragService::DRAGDROP_ACTION_COPY; + } - dragSession->SetDragAction ( action ); - } + dragSession->SetDragAction ( action ); + } } // SetDragActionBasedOnModifiers @@ -137,159 +137,166 @@ SetDragActionBasedOnModifiers ( nsIDragService* inDragService, short inModifiers //еее this should probably go into the drag session as a static pascal OSErr nsMacWindow :: DragTrackingHandler ( DragTrackingMessage theMessage, WindowPtr theWindow, - void *handlerRefCon, DragReference theDrag) + void *handlerRefCon, DragReference theDrag) { - // holds our drag service across multiple calls to this callback. The reference to - // the service is obtained when the mouse enters the window and is released when - // the mouse leaves the window (or there is a drop). This prevents us from having - // to re-establish the connection to the service manager 15 times a second when - // handling the |kDragTrackingInWindow| message. - static nsIDragService* sDragService = nsnull; + // holds our drag service across multiple calls to this callback. The reference to + // the service is obtained when the mouse enters the window and is released when + // the mouse leaves the window (or there is a drop). This prevents us from having + // to re-establish the connection to the service manager 15 times a second when + // handling the |kDragTrackingInWindow| message. + static nsIDragService* sDragService = nsnull; - nsMacWindow* geckoWindow = reinterpret_cast(handlerRefCon); - if ( !theWindow || !geckoWindow ) - return dragNotAcceptedErr; - - nsresult rv = NS_OK; - switch ( theMessage ) { - - case kDragTrackingEnterHandler: - break; - - case kDragTrackingEnterWindow: - { - // get our drag service for the duration of the drag. - nsresult rv = nsServiceManager::GetService(kCDragServiceCID, - NS_GET_IID(nsIDragService), - (nsISupports **)&sDragService); - NS_ASSERTION ( sDragService, "Couldn't get a drag service, we're in biiig trouble" ); - - // tell the session about this drag - if ( sDragService ) { - sDragService->StartDragSession(); - nsCOMPtr macSession ( do_QueryInterface(sDragService) ); - if ( macSession ) - macSession->SetDragReference ( theDrag ); - } - - // let gecko know that the mouse has entered the window so it - // can start tracking and sending enter/exit events to frames. - Point mouseLocGlobal; - ::GetDragMouse ( theDrag, &mouseLocGlobal, nsnull ); - geckoWindow->DragEvent ( NS_DRAGDROP_ENTER, mouseLocGlobal, 0L ); - break; - } - - case kDragTrackingInWindow: - { - Point mouseLocGlobal; - ::GetDragMouse ( theDrag, &mouseLocGlobal, nsnull ); - short modifiers; - ::GetDragModifiers ( theDrag, &modifiers, nsnull, nsnull ); - - NS_ASSERTION ( sDragService, "If we don't have a drag service, we're fucked" ); - - // set the drag action on the service so the frames know what is going on - SetDragActionBasedOnModifiers ( sDragService, modifiers ); - - // clear out the |canDrop| property of the drag session. If it's meant to - // be, it will be set again. - nsCOMPtr session; - sDragService->GetCurrentSession(getter_AddRefs(session)); - NS_ASSERTION ( session, "If we don't have a drag session, we're fucked" ); - if ( session ) - session->SetCanDrop(PR_FALSE); - - // pass into gecko for handling... - geckoWindow->DragEvent ( NS_DRAGDROP_OVER, mouseLocGlobal, modifiers ); - break; - } - - case kDragTrackingLeaveWindow: - { - // tell the drag service that we're done with it. - if ( sDragService ) { - sDragService->EndDragSession(); - - // clear out the dragRef in the drag session. We are guaranteed that - // this will be called _after_ the drop has been processed (if there - // is one), so we're not destroying valuable information if the drop - // was in our window. - nsCOMPtr macSession ( do_QueryInterface(sDragService) ); - if ( macSession ) - macSession->SetDragReference ( 0 ); - } + nsCOMPtr windowEventSink; + nsToolkit::GetWindowEventSink(theWindow, getter_AddRefs(windowEventSink)); + if ( !theWindow || !windowEventSink ) + return dragNotAcceptedErr; - // let gecko know that the mouse has left the window so it - // can stop tracking and sending enter/exit events to frames. - Point mouseLocGlobal; - ::GetDragMouse ( theDrag, &mouseLocGlobal, nsnull ); - geckoWindow->DragEvent ( NS_DRAGDROP_EXIT, mouseLocGlobal, 0L ); - - ::HideDragHilite ( theDrag ); - - // we're _really_ done with it, so let go of the service. - if ( sDragService ) { - nsServiceManager::ReleaseService(kCDragServiceCID, sDragService); - sDragService = nsnull; - } - - break; - } - - } // case of each drag message + nsresult rv = NS_OK; + switch ( theMessage ) { + + case kDragTrackingEnterHandler: + break; + + case kDragTrackingEnterWindow: + { + // get our drag service for the duration of the drag. + nsresult rv = nsServiceManager::GetService(kCDragServiceCID, + NS_GET_IID(nsIDragService), + (nsISupports **)&sDragService); + NS_ASSERTION ( sDragService, "Couldn't get a drag service, we're in biiig trouble" ); - return noErr; - + // tell the session about this drag + if ( sDragService ) { + sDragService->StartDragSession(); + nsCOMPtr macSession ( do_QueryInterface(sDragService) ); + if ( macSession ) + macSession->SetDragReference ( theDrag ); + } + + // let gecko know that the mouse has entered the window so it + // can start tracking and sending enter/exit events to frames. + Point mouseLocGlobal; + ::GetDragMouse ( theDrag, &mouseLocGlobal, nsnull ); + PRBool handled = PR_FALSE; + windowEventSink->DragEvent ( NS_DRAGDROP_ENTER, mouseLocGlobal.h, mouseLocGlobal.v, 0L, &handled ); + break; + } + + case kDragTrackingInWindow: + { + Point mouseLocGlobal; + ::GetDragMouse ( theDrag, &mouseLocGlobal, nsnull ); + short modifiers; + ::GetDragModifiers ( theDrag, &modifiers, nsnull, nsnull ); + + NS_ASSERTION ( sDragService, "If we don't have a drag service, we're fucked" ); + + // set the drag action on the service so the frames know what is going on + SetDragActionBasedOnModifiers ( sDragService, modifiers ); + + // clear out the |canDrop| property of the drag session. If it's meant to + // be, it will be set again. + nsCOMPtr session; + sDragService->GetCurrentSession(getter_AddRefs(session)); + NS_ASSERTION ( session, "If we don't have a drag session, we're fucked" ); + if ( session ) + session->SetCanDrop(PR_FALSE); + + // pass into gecko for handling... + PRBool handled = PR_FALSE; + windowEventSink->DragEvent ( NS_DRAGDROP_OVER, mouseLocGlobal.h, mouseLocGlobal.v, modifiers, &handled ); + break; + } + + case kDragTrackingLeaveWindow: + { + // tell the drag service that we're done with it. + if ( sDragService ) { + sDragService->EndDragSession(); + + // clear out the dragRef in the drag session. We are guaranteed that + // this will be called _after_ the drop has been processed (if there + // is one), so we're not destroying valuable information if the drop + // was in our window. + nsCOMPtr macSession ( do_QueryInterface(sDragService) ); + if ( macSession ) + macSession->SetDragReference ( 0 ); + } + + // let gecko know that the mouse has left the window so it + // can stop tracking and sending enter/exit events to frames. + Point mouseLocGlobal; + ::GetDragMouse ( theDrag, &mouseLocGlobal, nsnull ); + PRBool handled = PR_FALSE; + windowEventSink->DragEvent ( NS_DRAGDROP_EXIT, mouseLocGlobal.h, mouseLocGlobal.v, 0L, &handled ); + + ::HideDragHilite ( theDrag ); + + // we're _really_ done with it, so let go of the service. + if ( sDragService ) { + nsServiceManager::ReleaseService(kCDragServiceCID, sDragService); + sDragService = nsnull; + } + + break; + } + + } // case of each drag message + + return noErr; + } // DragTrackingHandler //еее this should probably go into the drag session as a static pascal OSErr nsMacWindow :: DragReceiveHandler (WindowPtr theWindow, void *handlerRefCon, - DragReference theDragRef) + DragReference theDragRef) { - // get our window back from the refCon - nsMacWindow* geckoWindow = reinterpret_cast(handlerRefCon); - if ( !theWindow || !geckoWindow ) - return dragNotAcceptedErr; + nsCOMPtr windowEventSink; + nsToolkit::GetWindowEventSink(theWindow, getter_AddRefs(windowEventSink)); + if ( !theWindow || !windowEventSink ) + return dragNotAcceptedErr; - // We make the assuption that the dragOver handlers have correctly set - // the |canDrop| property of the Drag Session. Before we dispatch the event - // into Gecko, check that value and either dispatch it or set the result - // code to "spring-back" and show the user the drag failed. - OSErr result = noErr; - nsCOMPtr dragService ( do_GetService(kCDragServiceCID) ); - if ( dragService ) { - nsCOMPtr dragSession; - dragService->GetCurrentSession ( getter_AddRefs(dragSession) ); - if ( dragSession ) { - // if the target has set that it can accept the drag, pass along - // to gecko, otherwise set phasers for failure. - PRBool canDrop = PR_FALSE; - if ( NS_SUCCEEDED(dragSession->GetCanDrop(&canDrop)) ) - if ( canDrop ) { - // pass the drop event along to Gecko - Point mouseLocGlobal; - ::GetDragMouse ( theDragRef, &mouseLocGlobal, nsnull ); - short modifiers; - ::GetDragModifiers ( theDragRef, &modifiers, nsnull, nsnull ); - geckoWindow->DragEvent ( NS_DRAGDROP_DROP, mouseLocGlobal, modifiers ); - } - else - result = dragNotAcceptedErr; - } // if a valid drag session + // We make the assuption that the dragOver handlers have correctly set + // the |canDrop| property of the Drag Session. Before we dispatch the event + // into Gecko, check that value and either dispatch it or set the result + // code to "spring-back" and show the user the drag failed. + OSErr result = noErr; + nsCOMPtr dragService ( do_GetService(kCDragServiceCID) ); + if ( dragService ) { + nsCOMPtr dragSession; + dragService->GetCurrentSession ( getter_AddRefs(dragSession) ); + if ( dragSession ) { + // if the target has set that it can accept the drag, pass along + // to gecko, otherwise set phasers for failure. + PRBool canDrop = PR_FALSE; + if ( NS_SUCCEEDED(dragSession->GetCanDrop(&canDrop)) ) + if ( canDrop ) { + // pass the drop event along to Gecko + Point mouseLocGlobal; + ::GetDragMouse ( theDragRef, &mouseLocGlobal, nsnull ); + short modifiers; + ::GetDragModifiers ( theDragRef, &modifiers, nsnull, nsnull ); + PRBool handled = PR_FALSE; + windowEventSink->DragEvent ( NS_DRAGDROP_DROP, mouseLocGlobal.h, mouseLocGlobal.v, modifiers, &handled ); + } + else + result = dragNotAcceptedErr; + } // if a valid drag session - // we don't need the drag session anymore, the user has released the - // mouse and the event has already gone to gecko. - dragService->EndDragSession(); - } - - return result; - + // we don't need the drag session anymore, the user has released the + // mouse and the event has already gone to gecko. + dragService->EndDragSession(); + } + + return result; + } // DragReceiveHandler +NS_IMPL_ISUPPORTS_INHERITED3(nsMacWindow, Inherited, nsIEventSink, nsPIWidgetMac, nsPIEventSinkStandalone); + //------------------------------------------------------------------------- // @@ -297,20 +304,20 @@ nsMacWindow :: DragReceiveHandler (WindowPtr theWindow, void *handlerRefCon, // //------------------------------------------------------------------------- nsMacWindow::nsMacWindow() : Inherited() - , mWindowMadeHere(PR_FALSE) - , mIsDialog(PR_FALSE) - , mMacEventHandler(nsnull) - , mAcceptsActivation(PR_TRUE) - , mIsActive(PR_FALSE) - , mZoomOnShow(PR_FALSE) + , mWindowMadeHere(PR_FALSE) + , mIsDialog(PR_FALSE) + , mMacEventHandler(nsnull) + , mAcceptsActivation(PR_TRUE) + , mIsActive(PR_FALSE) + , mZoomOnShow(PR_FALSE) #if !TARGET_CARBON - , mPhantomScrollbar(nsnull) - , mPhantomScrollbarData(nsnull) + , mPhantomScrollbar(nsnull) + , mPhantomScrollbarData(nsnull) #endif - , mResizeIsFromUs(PR_FALSE) + , mResizeIsFromUs(PR_FALSE) { - mMacEventHandler.reset(new nsMacEventHandler(this)); - WIDGET_SET_CLASSNAME("nsMacWindow"); + mMacEventHandler.reset(new nsMacEventHandler(this)); + WIDGET_SET_CLASSNAME("nsMacWindow"); // create handlers for drag&drop mDragTrackingHandlerUPP = NewDragTrackingHandlerUPP(DragTrackingHandler); @@ -325,36 +332,35 @@ nsMacWindow::nsMacWindow() : Inherited() //------------------------------------------------------------------------- nsMacWindow::~nsMacWindow() { - if (mWindowPtr) - { - // cleanup our special defproc if we are a popup + if (mWindowPtr) + { + // cleanup our special defproc if we are a popup if ( mWindowType == eWindowType_popup ) RemoveBorderlessDefProc ( mWindowPtr ); #if !TARGET_CARBON - // cleanup the struct we hang off the scrollbar's refcon - if ( mPhantomScrollbar ) { - ::SetControlReference(mPhantomScrollbar, (long)nsnull); - delete mPhantomScrollbarData; - } -#endif - if (mWindowMadeHere) - ::DisposeWindow(mWindowPtr); + // cleanup the struct we hang off the scrollbar's refcon + if ( mPhantomScrollbar ) { + ::SetControlReference(mPhantomScrollbar, (long)nsnull); + delete mPhantomScrollbarData; + } +#endif + if (mWindowMadeHere) + ::DisposeWindow(mWindowPtr); - // clean up DragManager stuff - if ( mDragTrackingHandlerUPP ) { - ::RemoveTrackingHandler ( mDragTrackingHandlerUPP, mWindowPtr ); - ::DisposeDragTrackingHandlerUPP ( mDragTrackingHandlerUPP ); - } - if ( mDragReceiveHandlerUPP ) { - ::RemoveReceiveHandler ( mDragReceiveHandlerUPP, mWindowPtr ); - ::DisposeDragReceiveHandlerUPP ( mDragReceiveHandlerUPP ); - } + // clean up DragManager stuff + if ( mDragTrackingHandlerUPP ) { + ::RemoveTrackingHandler ( mDragTrackingHandlerUPP, mWindowPtr ); + ::DisposeDragTrackingHandlerUPP ( mDragTrackingHandlerUPP ); + } + if ( mDragReceiveHandlerUPP ) { + ::RemoveReceiveHandler ( mDragReceiveHandlerUPP, mWindowPtr ); + ::DisposeDragReceiveHandlerUPP ( mDragReceiveHandlerUPP ); + } - nsMacMessageSink::RemoveRaptorWindowFromList(mWindowPtr); - mWindowPtr = nsnull; - } - + mWindowPtr = nsnull; + } + } @@ -365,66 +371,66 @@ nsMacWindow::~nsMacWindow() //------------------------------------------------------------------------- nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, - const nsRect &aRect, - EVENT_CALLBACK aHandleEventFunction, - nsIDeviceContext *aContext, - nsIAppShell *aAppShell, - nsIToolkit *aToolkit, - nsWidgetInitData *aInitData, - nsNativeWidget aNativeParent) + const nsRect &aRect, + EVENT_CALLBACK aHandleEventFunction, + nsIDeviceContext *aContext, + nsIAppShell *aAppShell, + nsIToolkit *aToolkit, + nsWidgetInitData *aInitData, + nsNativeWidget aNativeParent) { - short bottomPinDelta = 0; // # of pixels to subtract to pin window bottom - nsCOMPtr theToolkit = aToolkit; - - // build the main native window - if (aNativeParent == nsnull) - { - nsWindowType windowType; - if (aInitData) - { - mWindowType = aInitData->mWindowType; - // if a toplevel window was requested without a titlebar, use a dialog windowproc - if (aInitData->mWindowType == eWindowType_toplevel && - (aInitData->mBorderStyle == eBorderStyle_none || - aInitData->mBorderStyle != eBorderStyle_all && !(aInitData->mBorderStyle & eBorderStyle_title))) - windowType = eWindowType_dialog; - } else - mWindowType = (mIsDialog ? eWindowType_dialog : eWindowType_toplevel); + short bottomPinDelta = 0; // # of pixels to subtract to pin window bottom + nsCOMPtr theToolkit = aToolkit; + + // build the main native window + if (aNativeParent == nsnull) + { + nsWindowType windowType; + if (aInitData) + { + mWindowType = aInitData->mWindowType; + // if a toplevel window was requested without a titlebar, use a dialog windowproc + if (aInitData->mWindowType == eWindowType_toplevel && + (aInitData->mBorderStyle == eBorderStyle_none || + aInitData->mBorderStyle != eBorderStyle_all && !(aInitData->mBorderStyle & eBorderStyle_title))) + windowType = eWindowType_dialog; + } else + mWindowType = (mIsDialog ? eWindowType_dialog : eWindowType_toplevel); - short wDefProcID = kWindowDocumentProc; - Boolean goAwayFlag; - short hOffset; - short vOffset; + short wDefProcID = kWindowDocumentProc; + Boolean goAwayFlag; + short hOffset; + short vOffset; - switch (mWindowType) - { - case eWindowType_popup: - // 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()); + switch (mWindowType) + { + case eWindowType_popup: + // 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; - goAwayFlag = false; - hOffset = 0; - vOffset = 0; + goAwayFlag = false; + hOffset = 0; + vOffset = 0; #if TARGET_CARBON - wDefProcID = kWindowSimpleProc; + wDefProcID = kWindowSimpleProc; #else - wDefProcID = plainDBox; + wDefProcID = plainDBox; #endif break; - case eWindowType_child: - wDefProcID = plainDBox; - goAwayFlag = false; - hOffset = 0; - vOffset = 0; - break; + case eWindowType_child: + wDefProcID = plainDBox; + goAwayFlag = false; + hOffset = 0; + vOffset = 0; + break; - case eWindowType_dialog: + case eWindowType_dialog: if (aInitData) { // Prior to Carbon, defProcs were solely about appearance. If told to create a dialog, @@ -441,7 +447,7 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, switch (aInitData->mBorderStyle) { case eBorderStyle_none: - wDefProcID = kWindowModalDialogProc; + wDefProcID = kWindowModalDialogProc; break; case eBorderStyle_all: @@ -453,7 +459,7 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, break; case eBorderStyle_default: - wDefProcID = kWindowModalDialogProc; + wDefProcID = kWindowModalDialogProc; break; default: @@ -486,96 +492,103 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, } else { - wDefProcID = kWindowModalDialogProc; - goAwayFlag = true; // revisit this below + wDefProcID = kWindowModalDialogProc; + goAwayFlag = true; // revisit this below } hOffset = kDialogMarginWidth; vOffset = kDialogTitleBarHeight; - break; + break; - case eWindowType_toplevel: - if (aInitData && - aInitData->mBorderStyle != eBorderStyle_all && - aInitData->mBorderStyle != eBorderStyle_default && - (aInitData->mBorderStyle == eBorderStyle_none || - !(aInitData->mBorderStyle & eBorderStyle_resizeh))) - wDefProcID = kWindowDocumentProc; - else - wDefProcID = kWindowFullZoomGrowDocumentProc; - goAwayFlag = true; - hOffset = kWindowMarginWidth; - vOffset = kWindowTitleBarHeight; - break; + case eWindowType_toplevel: + if (aInitData && + aInitData->mBorderStyle != eBorderStyle_all && + aInitData->mBorderStyle != eBorderStyle_default && + (aInitData->mBorderStyle == eBorderStyle_none || + !(aInitData->mBorderStyle & eBorderStyle_resizeh))) + wDefProcID = kWindowDocumentProc; + else + wDefProcID = kWindowFullZoomGrowDocumentProc; + goAwayFlag = true; + hOffset = kWindowMarginWidth; + vOffset = kWindowTitleBarHeight; + break; case eWindowType_invisible: // don't do anything break; - } + } - // now turn off some default features if requested by aInitData - if (aInitData && aInitData->mBorderStyle != eBorderStyle_all) - { - if (aInitData->mBorderStyle == eBorderStyle_none || - aInitData->mBorderStyle == eBorderStyle_default && - windowType == eWindowType_dialog || - !(aInitData->mBorderStyle & eBorderStyle_close)) - goAwayFlag = false; - } + // now turn off some default features if requested by aInitData + if (aInitData && aInitData->mBorderStyle != eBorderStyle_all) + { + if (aInitData->mBorderStyle == eBorderStyle_none || + aInitData->mBorderStyle == eBorderStyle_default && + windowType == eWindowType_dialog || + !(aInitData->mBorderStyle & eBorderStyle_close)) + goAwayFlag = false; + } - Rect wRect; - nsRectToMacRect(aRect, wRect); + Rect wRect; + nsRectToMacRect(aRect, wRect); - if (eWindowType_popup != mWindowType) - ::OffsetRect(&wRect, hOffset, vOffset + ::GetMBarHeight()); - else - ::OffsetRect(&wRect, hOffset, vOffset); + if (eWindowType_popup != mWindowType) + ::OffsetRect(&wRect, hOffset, vOffset + ::GetMBarHeight()); + else + ::OffsetRect(&wRect, hOffset, vOffset); - nsCOMPtr screenmgr = do_GetService(sScreenManagerContractID); - if (screenmgr) { - nsCOMPtr screen; - //screenmgr->GetPrimaryScreen(getter_AddRefs(screen)); - screenmgr->ScreenForRect(wRect.left, wRect.top, - wRect.right - wRect.left, wRect.bottom - wRect.top, - getter_AddRefs(screen)); - if (screen) { - PRInt32 left, top, width, height; - screen->GetAvailRect(&left, &top, &width, &height); - if (wRect.bottom > top+height) { - bottomPinDelta = wRect.bottom - (top+height); - wRect.bottom -= bottomPinDelta; - } - } - } - mWindowPtr = ::NewCWindow(nil, &wRect, "\p", false, wDefProcID, (WindowRef)-1, goAwayFlag, (long)nsnull); - mWindowMadeHere = PR_TRUE; - } - else - { - mWindowPtr = (WindowPtr)aNativeParent; - mWindowMadeHere = PR_FALSE; - } + nsCOMPtr screenmgr = do_GetService(sScreenManagerContractID); + if (screenmgr) { + nsCOMPtr screen; + //screenmgr->GetPrimaryScreen(getter_AddRefs(screen)); + screenmgr->ScreenForRect(wRect.left, wRect.top, + wRect.right - wRect.left, wRect.bottom - wRect.top, + getter_AddRefs(screen)); + if (screen) { + PRInt32 left, top, width, height; + screen->GetAvailRect(&left, &top, &width, &height); + if (wRect.bottom > top+height) { + bottomPinDelta = wRect.bottom - (top+height); + wRect.bottom -= bottomPinDelta; + } + } + } + mWindowPtr = ::NewCWindow(nil, &wRect, "\p", false, wDefProcID, (WindowRef)-1, goAwayFlag, (long)nsnull); + mWindowMadeHere = PR_TRUE; + } + else + { + mWindowPtr = (WindowPtr)aNativeParent; + mWindowMadeHere = PR_FALSE; + } - if (mWindowPtr == nsnull) - return NS_ERROR_OUT_OF_MEMORY; + if (mWindowPtr == nsnull) + return NS_ERROR_OUT_OF_MEMORY; - nsMacMessageSink::AddRaptorWindowToList(mWindowPtr, this); + // Create the root control. + ControlHandle rootControl = nsnull; + if ( GetRootControl(mWindowPtr, &rootControl) != noErr ) { + OSErr err = CreateRootControl(mWindowPtr, &rootControl); + NS_ASSERTION(err == noErr, "Error creating window root control"); + } - // create the root control - ControlHandle rootControl = nil; - if (GetRootControl(mWindowPtr, &rootControl) != noErr) - { - OSErr err = CreateRootControl(mWindowPtr, &rootControl); - NS_ASSERTION(err == noErr, "Error creating window root control"); - } + // In order to get back to this nsIWidget from a WindowPtr, we hang + // ourselves off a property of the window. This allows places like + // 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 ); + NS_ASSERTION ( swpStatus == noErr, "couldn't set a property on the window, event handling will fail" ); + if ( swpStatus != noErr ) + return NS_ERROR_FAILURE; + + // reset the coordinates to (0,0) because it's the top level widget + // and adjust for any adjustment required to requested window bottom + nsRect bounds(0, 0, aRect.width, aRect.height - bottomPinDelta); - // reset the coordinates to (0,0) because it's the top level widget - // and adjust for any adjustment required to requested window bottom - nsRect bounds(0, 0, aRect.width, aRect.height - bottomPinDelta); - - // init base class + // init base class // (note: aParent is ignored. Mac (real) windows don't want parents) - Inherited::StandardCreate(nil, bounds, aHandleEventFunction, aContext, aAppShell, theToolkit, aInitData); + Inherited::StandardCreate(nil, bounds, aHandleEventFunction, aContext, aAppShell, theToolkit, aInitData); #if TARGET_CARBON if ( mWindowType == eWindowType_toplevel) @@ -598,9 +611,8 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, // created. Do so. We currently leave the collapse widget for all dialogs. ::ChangeWindowAttributes(mWindowPtr, 0L, kWindowCloseBoxAttribute ); } - - // Setup the live window resizing - if ( mWindowType == eWindowType_toplevel || mWindowType == eWindowType_invisible ) { + else if ( mWindowType == eWindowType_toplevel || mWindowType == eWindowType_invisible ) { + // Setup the live window resizing WindowAttributes removeAttributes = kWindowNoAttributes; if ( mWindowType == eWindowType_invisible ) removeAttributes |= kWindowInWindowMenuAttribute; @@ -647,22 +659,22 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, ::EmbedControl ( rootControl, mPhantomScrollbar ); #endif - // register tracking and receive handlers with the native Drag Manager - if ( mDragTrackingHandlerUPP ) { - OSErr result = ::InstallTrackingHandler ( mDragTrackingHandlerUPP, mWindowPtr, this ); - NS_ASSERTION ( result == noErr, "can't install drag tracking handler"); - } - if ( mDragReceiveHandlerUPP ) { - OSErr result = ::InstallReceiveHandler ( mDragReceiveHandlerUPP, mWindowPtr, this ); - NS_ASSERTION ( result == noErr, "can't install drag receive handler"); - } + // register tracking and receive handlers with the native Drag Manager + if ( mDragTrackingHandlerUPP ) { + OSErr result = ::InstallTrackingHandler ( mDragTrackingHandlerUPP, mWindowPtr, nsnull ); + NS_ASSERTION ( result == noErr, "can't install drag tracking handler"); + } + if ( mDragReceiveHandlerUPP ) { + OSErr result = ::InstallReceiveHandler ( mDragReceiveHandlerUPP, mWindowPtr, nsnull ); + 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; + return NS_OK; } @@ -675,11 +687,11 @@ nsMacWindow :: ScrollEventHandler ( EventHandlerCallRef inHandlerChain, EventRef SInt32 delta = 0; Point mouseLoc; OSErr err1 = ::GetEventParameter ( inEvent, kEventParamMouseWheelAxis, typeMouseWheelAxis, - NULL, sizeof(EventMouseWheelAxis), NULL, &axis ); + NULL, sizeof(EventMouseWheelAxis), NULL, &axis ); OSErr err2 = ::GetEventParameter ( inEvent, kEventParamMouseWheelDelta, typeLongInteger, - NULL, sizeof(SInt32), NULL, &delta ); + NULL, sizeof(SInt32), NULL, &delta ); OSErr err3 = ::GetEventParameter ( inEvent, kEventParamMouseLocation, typeQDPoint, - NULL, sizeof(Point), NULL, &mouseLoc ); + NULL, sizeof(Point), NULL, &mouseLoc ); if ( err1 == noErr && err2 == noErr && err3 == noErr ) { nsMacWindow* self = NS_REINTERPRET_CAST(nsMacWindow*, userData); @@ -732,7 +744,7 @@ nsMacWindow :: WindowEventHandler ( EventHandlerCallRef inHandlerChain, EventRef } break; } - + default: // do nothing... break; @@ -752,7 +764,7 @@ nsMacWindow :: WindowEventHandler ( EventHandlerCallRef inHandlerChain, EventRef // Create a nsMacWindow using a native window provided by the application // //------------------------------------------------------------------------- -NS_IMETHODIMP nsMacWindow::Create(nsNativeWidget aNativeParent, // this is a windowPtr +NS_IMETHODIMP nsMacWindow::Create(nsNativeWidget aNativeParent, // this is a windowPtr const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction, nsIDeviceContext *aContext, @@ -760,9 +772,9 @@ NS_IMETHODIMP nsMacWindow::Create(nsNativeWidget aNativeParent, // this is a wi nsIToolkit *aToolkit, nsWidgetInitData *aInitData) { - return(StandardCreate(nsnull, aRect, aHandleEventFunction, - aContext, aAppShell, aToolkit, aInitData, - aNativeParent)); + return(StandardCreate(nsnull, aRect, aHandleEventFunction, + aContext, aAppShell, aToolkit, aInitData, + aNativeParent)); } @@ -816,7 +828,7 @@ nsMacWindow :: RemoveBorderlessDefProc ( WindowPtr inWindow ) NS_IMETHODIMP nsMacWindow::Show(PRBool bState) { Inherited::Show(bState); - + // we need to make sure we call ::Show/HideWindow() to generate the // necessary activate/deactivate events. Calling ::ShowHide() is // not adequate, unless we don't want activation (popups). (pinkerton). @@ -838,12 +850,12 @@ NS_IMETHODIMP nsMacWindow::Show(PRBool bState) // be lurking. We want to catch this here because we're guaranteed that // we hide a window before we destroy it, and doing it here more closely // approximates where we do the same thing on windows. - if ( mWindowType == eWindowType_toplevel ) { - if ( gRollupListener ) + if ( mWindowType == eWindowType_toplevel ) { + if ( gRollupListener ) gRollupListener->Rollup(); NS_IF_RELEASE(gRollupListener); NS_IF_RELEASE(gRollupWidget); - } + } ::HideWindow(mWindowPtr); } @@ -870,61 +882,61 @@ NS_METHOD nsWindow::Restore(void) NS_IMETHODIMP nsMacWindow::ConstrainPosition(PRInt32 *aX, PRInt32 *aY) { - if (eWindowType_popup == mWindowType || !mWindowMadeHere) - return NS_OK; + if (eWindowType_popup == mWindowType || !mWindowMadeHere) + return NS_OK; - // Sanity check against screen size - // make sure the window stays visible + // Sanity check against screen size + // make sure the window stays visible - // get the window bounds - Rect portBounds; - ::GetWindowPortBounds(mWindowPtr, &portBounds); - short pos; - short windowWidth = portBounds.right - portBounds.left; - short windowHeight = portBounds.bottom - portBounds.top; + // get the window bounds + Rect portBounds; + ::GetWindowPortBounds(mWindowPtr, &portBounds); + short pos; + short windowWidth = portBounds.right - portBounds.left; + short windowHeight = portBounds.bottom - portBounds.top; - // now get our playing field. use the current screen, or failing that for any reason, - // the GrayRgn (which of course is arguably more correct but has drawbacks as well) - Rect screenRect; - nsCOMPtr screenmgr = do_GetService(sScreenManagerContractID); - if (screenmgr) { - nsCOMPtr screen; - PRInt32 left, top, width, height, fullHeight; + // now get our playing field. use the current screen, or failing that for any reason, + // the GrayRgn (which of course is arguably more correct but has drawbacks as well) + Rect screenRect; + nsCOMPtr screenmgr = do_GetService(sScreenManagerContractID); + if (screenmgr) { + nsCOMPtr screen; + PRInt32 left, top, width, height, fullHeight; - // zero size rects can happen during window creation, and confuse - // the screen manager - width = windowWidth > 0 ? windowWidth : 1; - height = windowHeight > 0 ? windowHeight : 1; - screenmgr->ScreenForRect(*aX, *aY, width, height, - getter_AddRefs(screen)); - if (screen) { - screen->GetAvailRect(&left, &top, &width, &height); - screen->GetRect(&left, &top, &width, &fullHeight); - screenRect.left = left; - screenRect.right = left+width; - screenRect.top = top; - screenRect.bottom = top+height; - } - } else - ::GetRegionBounds(::GetGrayRgn(), &screenRect); + // zero size rects can happen during window creation, and confuse + // the screen manager + width = windowWidth > 0 ? windowWidth : 1; + height = windowHeight > 0 ? windowHeight : 1; + screenmgr->ScreenForRect(*aX, *aY, width, height, + getter_AddRefs(screen)); + if (screen) { + screen->GetAvailRect(&left, &top, &width, &height); + screen->GetRect(&left, &top, &width, &fullHeight); + screenRect.left = left; + screenRect.right = left+width; + screenRect.top = top; + screenRect.bottom = top+height; + } + } else + ::GetRegionBounds(::GetGrayRgn(), &screenRect); - pos = screenRect.left; - if (windowWidth > kWindowPositionSlop) - pos -= windowWidth - kWindowPositionSlop; - if (*aX < pos) - *aX = pos; - else if (*aX >= screenRect.right - kWindowPositionSlop) - *aX = screenRect.right - kWindowPositionSlop; + pos = screenRect.left; + if (windowWidth > kWindowPositionSlop) + pos -= windowWidth - kWindowPositionSlop; + if (*aX < pos) + *aX = pos; + else if (*aX >= screenRect.right - kWindowPositionSlop) + *aX = screenRect.right - kWindowPositionSlop; - pos = screenRect.top; - if (windowHeight > kWindowPositionSlop) - pos -= windowHeight - kWindowPositionSlop; - if (*aY < pos) - *aY = pos; - else if (*aY >= screenRect.bottom - kWindowPositionSlop) - *aY = screenRect.bottom - kWindowPositionSlop; + pos = screenRect.top; + if (windowHeight > kWindowPositionSlop) + pos -= windowHeight - kWindowPositionSlop; + if (*aY < pos) + *aY = pos; + else if (*aY >= screenRect.bottom - kWindowPositionSlop) + *aY = screenRect.bottom - kWindowPositionSlop; - return NS_OK; + return NS_OK; } //------------------------------------------------------------------------- @@ -939,87 +951,87 @@ NS_IMETHODIMP nsMacWindow::Move(PRInt32 aX, PRInt32 aY) { StPortSetter setOurPortForLocalToGlobal ( mWindowPtr ); - if (eWindowType_popup == mWindowType) { - PRInt32 xOffset=0,yOffset=0; - nsRect localRect,globalRect; + if (eWindowType_popup == mWindowType) { + PRInt32 xOffset=0,yOffset=0; + nsRect localRect,globalRect; - // convert to screen coordinates - localRect.x = aX; - localRect.y = aY; - localRect.width = 100; - localRect.height = 100; + // convert to screen coordinates + localRect.x = aX; + localRect.y = aY; + localRect.width = 100; + localRect.height = 100; - if ( mOffsetParent ) { - mOffsetParent->WidgetToScreen(localRect,globalRect); - aX=globalRect.x; - aY=globalRect.y; - - // there is a bug on OSX where if we call ::MoveWindow() with the same - // coordinates (within a pixel or two) as a window's current location, it will - // move to (0,0,-1,-1). The fix is to not move the window if we're already - // there. (radar# 2669004) + if ( mOffsetParent ) { + mOffsetParent->WidgetToScreen(localRect,globalRect); + aX=globalRect.x; + aY=globalRect.y; + + // there is a bug on OSX where if we call ::MoveWindow() with the same + // coordinates (within a pixel or two) as a window's current location, it will + // move to (0,0,-1,-1). The fix is to not move the window if we're already + // there. (radar# 2669004) #if TARGET_CARBON const PRInt32 kMoveThreshold = 2; #else const PRInt32 kMoveThreshold = 0; #endif - Rect currBounds; - ::GetWindowBounds ( mWindowPtr, kWindowGlobalPortRgn, &currBounds ); - if ( abs(currBounds.left-aX) > kMoveThreshold || abs(currBounds.top-aY) > kMoveThreshold ) { - ::MoveWindow(mWindowPtr, aX, aY, false); - - Rect newBounds; - ::GetWindowBounds ( mWindowPtr, kWindowGlobalPortRgn, &newBounds ); - } - } + Rect currBounds; + ::GetWindowBounds ( mWindowPtr, kWindowGlobalPortRgn, &currBounds ); + if ( abs(currBounds.left-aX) > kMoveThreshold || abs(currBounds.top-aY) > kMoveThreshold ) { + ::MoveWindow(mWindowPtr, aX, aY, false); + + Rect newBounds; + ::GetWindowBounds ( mWindowPtr, kWindowGlobalPortRgn, &newBounds ); + } + } - return NS_OK; - } else if (mWindowMadeHere) { - Rect portBounds; - ::GetWindowPortBounds(mWindowPtr, &portBounds); + return NS_OK; + } else if (mWindowMadeHere) { + Rect portBounds; + ::GetWindowPortBounds(mWindowPtr, &portBounds); - if (mIsDialog) { - aX += kDialogMarginWidth; - aY += kDialogTitleBarHeight; - } else { - aX += kWindowMarginWidth; - aY += kWindowTitleBarHeight; - } + if (mIsDialog) { + aX += kDialogMarginWidth; + aY += kDialogTitleBarHeight; + } else { + aX += kWindowMarginWidth; + aY += kWindowTitleBarHeight; + } - nsCOMPtr screenmgr = do_GetService(sScreenManagerContractID); - if (screenmgr) { - nsCOMPtr screen; - PRInt32 left, top, width, height, fullTop; - // adjust for unset bounds, which confuses the screen manager - width = portBounds.right - portBounds.left; - height = portBounds.bottom - portBounds.top; - if (height <= 0) height = 1; - if (width <= 0) width = 1; + nsCOMPtr screenmgr = do_GetService(sScreenManagerContractID); + if (screenmgr) { + nsCOMPtr screen; + PRInt32 left, top, width, height, fullTop; + // adjust for unset bounds, which confuses the screen manager + width = portBounds.right - portBounds.left; + height = portBounds.bottom - portBounds.top; + if (height <= 0) height = 1; + if (width <= 0) width = 1; - screenmgr->ScreenForRect(aX, aY, width, height, - getter_AddRefs(screen)); - if (screen) { - screen->GetAvailRect(&left, &top, &width, &height); - screen->GetRect(&left, &fullTop, &width, &height); - aY += top-fullTop; - } - } + screenmgr->ScreenForRect(aX, aY, width, height, + getter_AddRefs(screen)); + if (screen) { + screen->GetAvailRect(&left, &top, &width, &height); + screen->GetRect(&left, &fullTop, &width, &height); + aY += top-fullTop; + } + } - // move the window if it has not been moved yet - // (ie. if this function isn't called in response to a DragWindow event) - Point macPoint = topLeft(portBounds); - ::LocalToGlobal(&macPoint); - if (macPoint.h != aX || macPoint.v != aY) - ::MoveWindow(mWindowPtr, aX, aY, false); + // move the window if it has not been moved yet + // (ie. if this function isn't called in response to a DragWindow event) + Point macPoint = topLeft(portBounds); + ::LocalToGlobal(&macPoint); + if (macPoint.h != aX || macPoint.v != aY) + ::MoveWindow(mWindowPtr, aX, aY, false); - // propagate the event in global coordinates - Inherited::Move(aX, aY); + // propagate the event in global coordinates + Inherited::Move(aX, aY); - // reset the coordinates to (0,0) because it's the top level widget - mBounds.x = 0; - mBounds.y = 0; - } - return NS_OK; + // reset the coordinates to (0,0) because it's the top level widget + mBounds.x = 0; + mBounds.y = 0; + } + return NS_OK; } //------------------------------------------------------------------------- @@ -1081,7 +1093,15 @@ NS_METHOD nsMacWindow::SetSizeMode(PRInt32 aMode) return rv; } -void nsMacWindow::CalculateAndSetZoomedSize() + +// +// CalculateAndSetZoomedSize +// +// Recomputes the zoomed window size taking things such as window chrome, +// dock position, menubar, and finder icons into account +// +NS_IMETHODIMP +nsMacWindow::CalculateAndSetZoomedSize() { StPortSetter setOurPort(mWindowPtr); @@ -1116,7 +1136,7 @@ void nsMacWindow::CalculateAndSetZoomedSize() // find which screen the window is (mostly) on and get its rect. GetAvailRect() // handles subtracting out the menubar and the dock for us. Set the zoom rect // to the screen rect, less some fudging and room for icons on the primary screen. - nsCOMPtr screenMgr = do_GetService(sScreenManagerContractID); + nsCOMPtr screenMgr = do_GetService(sScreenManagerContractID); if ( screenMgr ) { nsCOMPtr screen; screenMgr->ScreenForRect ( windRect.left, windRect.top, windRect.right - windRect.left, windRect.bottom - windRect.top, @@ -1138,16 +1158,18 @@ void nsMacWindow::CalculateAndSetZoomedSize() newWindowRect.width -= iconSpace; } - Rect zoomRect; - ::SetRect(&zoomRect, + Rect zoomRect; + ::SetRect(&zoomRect, newWindowRect.x + wLeftBorder, newWindowRect.y + wTitleHeight, newWindowRect.x + newWindowRect.width - wRightBorder, newWindowRect.y + newWindowRect.height - wBottomBorder); - ::SetWindowStandardState ( mWindowPtr, &zoomRect ); + ::SetWindowStandardState ( mWindowPtr, &zoomRect ); } } + return NS_OK; + } // CalculateAndSetZoomedSize @@ -1163,37 +1185,37 @@ void nsMacWindow::CalculateAndSetZoomedSize() //------------------------------------------------------------------------- void nsMacWindow::MoveToGlobalPoint(PRInt32 aX, PRInt32 aY) { - PRInt32 left, top, width, height, fullTop; - Rect portBounds; + PRInt32 left, top, width, height, fullTop; + Rect portBounds; - StPortSetter doThatThingYouDo(mWindowPtr); - ::GetWindowPortBounds(mWindowPtr, &portBounds); + StPortSetter doThatThingYouDo(mWindowPtr); + ::GetWindowPortBounds(mWindowPtr, &portBounds); - width = portBounds.right - portBounds.left; - height = portBounds.bottom - portBounds.top; - ::LocalToGlobal(&topLeft(portBounds)); + width = portBounds.right - portBounds.left; + height = portBounds.bottom - portBounds.top; + ::LocalToGlobal(&topLeft(portBounds)); - nsCOMPtr screenmgr = do_GetService(sScreenManagerContractID); - if (screenmgr) { - nsCOMPtr screen; - //screenmgr->GetPrimaryScreen(getter_AddRefs(screen)); - screenmgr->ScreenForRect(portBounds.left, portBounds.top, width, height, - getter_AddRefs(screen)); - if (screen) { - screen->GetAvailRect(&left, &top, &width, &height); - screen->GetRect(&left, &fullTop, &width, &height); - aY -= top-fullTop; - } - } + nsCOMPtr screenmgr = do_GetService(sScreenManagerContractID); + if (screenmgr) { + nsCOMPtr screen; + //screenmgr->GetPrimaryScreen(getter_AddRefs(screen)); + screenmgr->ScreenForRect(portBounds.left, portBounds.top, width, height, + getter_AddRefs(screen)); + if (screen) { + screen->GetAvailRect(&left, &top, &width, &height); + screen->GetRect(&left, &fullTop, &width, &height); + aY -= top-fullTop; + } + } - if (mIsDialog) { - aX -= kDialogMarginWidth; - aY -= kDialogTitleBarHeight; - } else { - aX -= kWindowMarginWidth; - aY -= kWindowTitleBarHeight; - } - Move(aX, aY); + if (mIsDialog) { + aX -= kDialogMarginWidth; + aY -= kDialogTitleBarHeight; + } else { + aX -= kWindowMarginWidth; + aY -= kWindowTitleBarHeight; + } + Move(aX, aY); } //------------------------------------------------------------------------- @@ -1203,10 +1225,10 @@ void nsMacWindow::MoveToGlobalPoint(PRInt32 aX, PRInt32 aY) //------------------------------------------------------------------------- NS_IMETHODIMP nsMacWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint) { - if (mWindowMadeHere) { + if (mWindowMadeHere) { // Sanity check against screen size Rect screenRect; - ::GetRegionBounds(::GetGrayRgn(), &screenRect); + ::GetRegionBounds(::GetGrayRgn(), &screenRect); // Need to use non-negative coordinates PRInt32 screenWidth; @@ -1226,19 +1248,19 @@ NS_IMETHODIMP nsMacWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepai if(aWidth > screenWidth) aWidth = screenWidth; - - Rect macRect; - ::GetWindowPortBounds ( mWindowPtr, &macRect ); + + Rect macRect; + ::GetWindowPortBounds ( mWindowPtr, &macRect ); short w = macRect.right - macRect.left; short h = macRect.bottom - macRect.top; Boolean needReposition = (w == 1 && h == 1); - if ((w != aWidth) || (h != aHeight)) - { - // make sure that we don't infinitely recurse if live-resize is on + if ((w != aWidth) || (h != aHeight)) + { + // make sure that we don't infinitely recurse if live-resize is on mResizeIsFromUs = PR_TRUE; - ::SizeWindow(mWindowPtr, aWidth, aHeight, aRepaint); + ::SizeWindow(mWindowPtr, aWidth, aHeight, aRepaint); mResizeIsFromUs = PR_FALSE; #if defined(XP_MACOSX) @@ -1246,43 +1268,43 @@ NS_IMETHODIMP nsMacWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepai if (needReposition) RepositionWindow(mWindowPtr, NULL, kWindowCascadeOnMainScreen); #endif - } - } - Inherited::Resize(aWidth, aHeight, aRepaint); - return NS_OK; + } + } + Inherited::Resize(aWidth, aHeight, aRepaint); + return NS_OK; } NS_IMETHODIMP nsMacWindow::GetScreenBounds(nsRect &aRect) { - nsRect localBounds; - PRInt32 yAdjust = 0; + nsRect localBounds; + PRInt32 yAdjust = 0; - GetBounds(localBounds); - // nsMacWindow local bounds are always supposed to be local (0,0) but in the middle of a move - // can be global. This next adjustment assures they are in local coordinates, even then. - localBounds.MoveBy(-localBounds.x, -localBounds.y); - WidgetToScreen(localBounds, aRect); + GetBounds(localBounds); + // nsMacWindow local bounds are always supposed to be local (0,0) but in the middle of a move + // can be global. This next adjustment assures they are in local coordinates, even then. + localBounds.MoveBy(-localBounds.x, -localBounds.y); + WidgetToScreen(localBounds, aRect); - nsCOMPtr screenmgr = do_GetService(sScreenManagerContractID); - if (screenmgr) { - nsCOMPtr screen; - //screenmgr->GetPrimaryScreen(getter_AddRefs(screen)); - screenmgr->ScreenForRect(aRect.x, aRect.y, aRect.width, aRect.height, - getter_AddRefs(screen)); - if (screen) { - PRInt32 left, top, width, height, fullTop; - screen->GetAvailRect(&left, &top, &width, &height); - screen->GetRect(&left, &fullTop, &width, &height); - yAdjust = top-fullTop; - } - } + nsCOMPtr screenmgr = do_GetService(sScreenManagerContractID); + if (screenmgr) { + nsCOMPtr screen; + //screenmgr->GetPrimaryScreen(getter_AddRefs(screen)); + screenmgr->ScreenForRect(aRect.x, aRect.y, aRect.width, aRect.height, + getter_AddRefs(screen)); + if (screen) { + PRInt32 left, top, width, height, fullTop; + screen->GetAvailRect(&left, &top, &width, &height); + screen->GetRect(&left, &fullTop, &width, &height); + yAdjust = top-fullTop; + } + } - if (mIsDialog) - aRect.MoveBy(-kDialogMarginWidth, -kDialogTitleBarHeight-yAdjust); - else - aRect.MoveBy(-kWindowMarginWidth, -kWindowTitleBarHeight-yAdjust); + if (mIsDialog) + aRect.MoveBy(-kDialogMarginWidth, -kDialogTitleBarHeight-yAdjust); + else + aRect.MoveBy(-kWindowMarginWidth, -kWindowTitleBarHeight-yAdjust); - return NS_OK; + return NS_OK; } //------------------------------------------------------------------------- @@ -1291,7 +1313,7 @@ NS_IMETHODIMP nsMacWindow::GetScreenBounds(nsRect &aRect) { //------------------------------------------------------------------------- PRBool nsMacWindow::OnPaint(nsPaintEvent &event) { - return PR_TRUE; // don't dispatch the update event + return PR_TRUE; // don't dispatch the update event } //------------------------------------------------------------------------- @@ -1320,67 +1342,84 @@ NS_IMETHODIMP nsMacWindow::SetTitle(const nsString& aTitle) } -//------------------------------------------------------------------------- +#pragma mark - + + // -// Handle OS events +// DispatchEvent // -//------------------------------------------------------------------------- -PRBool nsMacWindow::HandleOSEvent ( EventRecord& aOSEvent ) +// Handle an event coming into us and send it to gecko. +// +NS_IMETHODIMP +nsMacWindow::DispatchEvent ( void* anEvent, PRBool *_retval ) { - PRBool retVal; - if (mMacEventHandler.get()) - retVal = mMacEventHandler->HandleOSEvent(aOSEvent); - else - retVal = PR_FALSE; - return retVal; + *_retval = PR_FALSE; + if (mMacEventHandler.get()) + *_retval = mMacEventHandler->HandleOSEvent(*NS_REINTERPRET_CAST(EventRecord*,anEvent)); + + return NS_OK; } +// +// DispatchEvent +// +// Handle an event coming into us and send it to gecko. +// +NS_IMETHODIMP +nsMacWindow::DispatchMenuEvent ( void* anEvent, PRInt32 aNativeResult, PRBool *_retval ) +{ #if USE_MENUSELECT - -//------------------------------------------------------------------------- -// -// Handle Menu commands -// -//------------------------------------------------------------------------- -PRBool nsMacWindow::HandleMenuCommand ( EventRecord& aOSEvent, long aMenuResult ) -{ - PRBool retVal; - if (mMacEventHandler.get()) - retVal = mMacEventHandler->HandleMenuCommand(aOSEvent, aMenuResult); - else - retVal = PR_FALSE; - return retVal; -} - + *_retval = PR_FALSE; + if (mMacEventHandler.get()) + *_retval = mMacEventHandler->HandleMenuCommand(*NS_REINTERPRET_CAST(EventRecord*,anEvent), aNativeResult); #endif -//------------------------------------------------------------------------- -// Pass notification of some drag event to Gecko + return NS_OK; +} + + +// +// DragEvent // // The drag manager has let us know that something related to a drag has // occurred in this window. It could be any number of things, ranging from // a drop, to a drag enter/leave, or a drag over event. The actual event // is passed in |aMessage| and is passed along to our event hanlder so Gecko // knows about it. -//------------------------------------------------------------------------- -PRBool nsMacWindow::DragEvent ( unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers ) +// +NS_IMETHODIMP +nsMacWindow::DragEvent(PRUint32 aMessage, PRInt16 aMouseGlobalX, PRInt16 aMouseGlobalY, + PRUint16 aKeyModifiers, PRBool *_retval) { - PRBool retVal; - if (mMacEventHandler.get()) - retVal = mMacEventHandler->DragEvent(aMessage, aMouseGlobal, aKeyModifiers); - else - retVal = PR_FALSE; - return retVal; + *_retval = PR_FALSE; + Point globalPoint = {aMouseGlobalY, aMouseGlobalX}; // QD Point stored as v, h + if (mMacEventHandler.get()) + *_retval = mMacEventHandler->DragEvent(aMessage, globalPoint, aKeyModifiers); + + return NS_OK; } + +NS_IMETHODIMP +nsMacWindow::Idle() +{ + // do some idle stuff? + return NS_ERROR_NOT_IMPLEMENTED; +} + + +#pragma mark - + + //------------------------------------------------------------------------- // // Like ::BringToFront, but constrains the window to its z-level // //------------------------------------------------------------------------- -void nsMacWindow::ComeToFront() { - +NS_IMETHODIMP +nsMacWindow::ComeToFront() +{ nsZLevelEvent event; event.point.x = mBounds.x; @@ -1397,12 +1436,14 @@ void nsMacWindow::ComeToFront() { event.mAdjusted = PR_FALSE; DispatchWindowEvent(event); + + return NS_OK; } NS_IMETHODIMP nsMacWindow::ResetInputState() { - return mMacEventHandler->ResetInputState(); + return mMacEventHandler->ResetInputState(); } void nsMacWindow::SetIsActive(PRBool aActive) diff --git a/widget/src/mac/nsMacWindow.h b/widget/src/mac/nsMacWindow.h index 29b8ecf9415c..f5b06cbb4dc5 100644 --- a/widget/src/mac/nsMacWindow.h +++ b/widget/src/mac/nsMacWindow.h @@ -44,6 +44,9 @@ using std::auto_ptr; #include "nsWindow.h" #include "nsMacEventHandler.h" +#include "nsIEventSink.h" +#include "nsPIWidgetMac.h" +#include "nsPIEventSinkStandalone.h" #if TARGET_CARBON #include @@ -59,7 +62,7 @@ struct PhantomScrollbarData; //------------------------------------------------------------------------- // MacOS native window -class nsMacWindow : public nsChildWindow +class nsMacWindow : public nsChildWindow, public nsIEventSink, public nsPIWidgetMac, public nsPIEventSinkStandalone { private: typedef nsChildWindow Inherited; @@ -68,6 +71,11 @@ public: nsMacWindow(); virtual ~nsMacWindow(); + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIEVENTSINK + NS_DECL_NSPIWIDGETMAC + NS_DECL_NSPIEVENTSINKSTANDALONE + /* // nsIWidget interface NS_IMETHOD Create(nsIWidget *aParent, @@ -103,7 +111,6 @@ public: NS_IMETHOD Move(PRInt32 aX, PRInt32 aY); NS_IMETHOD PlaceBehind(nsIWidget *aWidget, PRBool aActivate); NS_IMETHOD SetSizeMode(PRInt32 aMode); - void CalculateAndSetZoomedSize(); NS_IMETHOD Resize(PRInt32 aWidth,PRInt32 aHeight, PRBool aRepaint); NS_IMETHOD GetScreenBounds(nsRect &aRect); @@ -111,20 +118,6 @@ public: NS_IMETHOD SetTitle(const nsString& aTitle); - virtual PRBool HandleOSEvent( - EventRecord& aOSEvent); - -#if USE_MENUSELECT - virtual PRBool HandleMenuCommand( - EventRecord& aOSEvent, - long aMenuResult); -#endif - - // be notified that a some form of drag event needs to go into Gecko - virtual PRBool DragEvent ( unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers ) ; - - void ComeToFront(); - // nsIKBStateControl interface NS_IMETHOD ResetInputState(); diff --git a/widget/src/mac/nsPIEventSinkStandalone.idl b/widget/src/mac/nsPIEventSinkStandalone.idl new file mode 100644 index 000000000000..81a729674c26 --- /dev/null +++ b/widget/src/mac/nsPIEventSinkStandalone.idl @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Mozilla browser. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + + +#include "nsISupports.idl" + + +/** + * The nsPIEventSinkStandalone is implemented internally by Gecko as the conduit + * through which native menu events travel into Gecko. You obtain an + * event sink by QI'ing the top-level nsIWidget, usually a window. + * + * This api extends nsIEventSink for events that the stand-alone mozilla + * client needs but embedding does not. It is not intended to be public. + */ + +[uuid(912fa496-91ab-4bba-b502-524218ffb1b1)] +interface nsPIEventSinkStandalone : nsISupports +{ + /** + * Entry point for native menu events into Gecko. + * + * @return PR_TRUE if event was handled + * PR_FALSE if not handled + * + * @param anEvent a native EventRecord*. + * @param aNativeResult the result of ::MenuSelect(). + */ + boolean dispatchMenuEvent ( in voidPtr anEvent, in long aNativeResult ) ; +}; \ No newline at end of file diff --git a/widget/src/mac/nsPIWidgetMac.idl b/widget/src/mac/nsPIWidgetMac.idl new file mode 100644 index 000000000000..966e5526b37b --- /dev/null +++ b/widget/src/mac/nsPIWidgetMac.idl @@ -0,0 +1,43 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corp. Portions created by Netscape are Copyright (C) 1999 Netscape + * Communications Corp. All Rights Reserved. + * + * Contributor(s): + * Mike Pinkerton + */ + +#include "nsISupports.idl" + + +// +// nsPIWidgetMac +// +// A private interface (unfrozen, private to the widget implementation) that +// gives us access to some extra features on a widget/window. +// +[scriptable, uuid(59356b39-2031-4fd2-a856-435cda1ef700)] +interface nsPIWidgetMac : nsISupports +{ + // Like OS ::BringToFront, but constrains the window to its z-level + void ComeToFront ( ) ; + + // Recomputes the zoomed window size taking things such as window chrome, + // dock position, menubar, and finder icons into account + void CalculateAndSetZoomedSize ( ); + +}; // nsPIWidgetMac + diff --git a/widget/src/mac/nsToolkit.cpp b/widget/src/mac/nsToolkit.cpp index fff501e807d7..711bd1f9503a 100644 --- a/widget/src/mac/nsToolkit.cpp +++ b/widget/src/mac/nsToolkit.cpp @@ -36,13 +36,15 @@ * ***** END LICENSE BLOCK ***** */ #include "nsToolkit.h" -#include "nsWindow.h" +#include "nsIWidget.h" #include "nsGUIEvent.h" #include "nsWidgetAtoms.h" #include #include +#include "nsIEventSink.h" + #include "nsIEventQueue.h" #include "nsIEventQueueService.h" #include "nsIServiceManager.h" @@ -265,6 +267,45 @@ nsToolkit :: IsAppInForeground ( ) } +// +// GetTopWidget +// +// We've stashed the nsIWidget for the given windowPtr in the data +// properties of the window. Fetch it. +// +void +nsToolkit::GetTopWidget ( WindowPtr aWindow, nsIWidget** outWidget ) +{ + nsIWidget* topLevelWidget = nsnull; + ::GetWindowProperty ( aWindow, 'MOSS', 'GEKO', sizeof(nsIWidget*), nsnull, (void*)&topLevelWidget); + if ( topLevelWidget ) { + *outWidget = topLevelWidget; + NS_ADDREF(*outWidget); + } +} + + +// +// GetWindowEventSink +// +// We've stashed the nsIEventSink for the given windowPtr in the data +// properties of the window. Fetch it. +// +void +nsToolkit::GetWindowEventSink ( WindowPtr aWindow, nsIEventSink** outSink ) +{ + *outSink = nsnull; + + nsCOMPtr topWidget; + GetTopWidget ( aWindow, getter_AddRefs(topWidget) ); + nsCOMPtr sink ( do_QueryInterface(topWidget) ); + if ( sink ) { + *outSink = sink; + NS_ADDREF(*outSink); + } +} + + //------------------------------------------------------------------------- // // Return the nsIToolkit for the current thread. If a toolkit does not diff --git a/widget/src/mac/nsToolkit.h b/widget/src/mac/nsToolkit.h index 149283e0817f..2436ecda9e2b 100644 --- a/widget/src/mac/nsToolkit.h +++ b/widget/src/mac/nsToolkit.h @@ -70,6 +70,10 @@ #include +class nsIEventSink; +class nsIWidget; + + class nsToolkit : public nsIToolkit { @@ -94,6 +98,11 @@ public: static void AppInBackground ( ) ; static bool IsAppInForeground ( ) ; + // utility routines for getting the toplevel widget and event sink + // stashed in properties of the window. + static void GetWindowEventSink ( WindowPtr aWindow, nsIEventSink** outSink ) ; + static void GetTopWidget ( WindowPtr aWindow, nsIWidget** outWidget ) ; + protected: bool mInited; static bool sInForeground;