From c8a2fb249fffd0884abd5e05e8ef40ef3e0563ef Mon Sep 17 00:00:00 2001 From: John Daniels Date: Sat, 18 Oct 2008 20:13:27 -0500 Subject: [PATCH] Bug 459075 - "Unnecessary nsCommonWidget class in GTK code" [r+sr=roc] --- widget/src/gtk2/Makefile.in | 1 - widget/src/gtk2/nsAppShell.cpp | 1 - widget/src/gtk2/nsCommonWidget.cpp | 402 ----------------------------- widget/src/gtk2/nsCommonWidget.h | 161 ------------ widget/src/gtk2/nsWindow.cpp | 383 ++++++++++++++++++++++++++- widget/src/gtk2/nsWindow.h | 111 +++++++- 6 files changed, 472 insertions(+), 587 deletions(-) delete mode 100644 widget/src/gtk2/nsCommonWidget.cpp delete mode 100644 widget/src/gtk2/nsCommonWidget.h diff --git a/widget/src/gtk2/Makefile.in b/widget/src/gtk2/Makefile.in index 091094d249a..18fd290f449 100644 --- a/widget/src/gtk2/Makefile.in +++ b/widget/src/gtk2/Makefile.in @@ -94,7 +94,6 @@ CPPSRCS = \ nsWidgetFactory.cpp \ nsToolkit.cpp \ nsBidiKeyboard.cpp \ - nsCommonWidget.cpp \ nsLookAndFeel.cpp \ nsGtkKeyUtils.cpp \ nsFilePicker.cpp \ diff --git a/widget/src/gtk2/nsAppShell.cpp b/widget/src/gtk2/nsAppShell.cpp index 72710aeccd6..0724660d294 100644 --- a/widget/src/gtk2/nsAppShell.cpp +++ b/widget/src/gtk2/nsAppShell.cpp @@ -41,7 +41,6 @@ #include #include #include -#include "nsCommonWidget.h" #include "nsAppShell.h" #include "prlog.h" #include "prenv.h" diff --git a/widget/src/gtk2/nsCommonWidget.cpp b/widget/src/gtk2/nsCommonWidget.cpp deleted file mode 100644 index a90354ca4b5..00000000000 --- a/widget/src/gtk2/nsCommonWidget.cpp +++ /dev/null @@ -1,402 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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.org code. - * - * The Initial Developer of the Original Code is Christopher Blizzard - * . Portions created by the Initial Developer - * are Copyright (C) 2001 the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsCommonWidget.h" -#include "nsGtkKeyUtils.h" - -nsCommonWidget::nsCommonWidget() -{ - mIsTopLevel = PR_FALSE; - mIsDestroyed = PR_FALSE; - mNeedsResize = PR_FALSE; - mNeedsMove = PR_FALSE; - mListenForResizes = PR_FALSE; - mIsShown = PR_FALSE; - mNeedsShow = PR_FALSE; - mEnabled = PR_TRUE; - mCreated = PR_FALSE; - mPlaced = PR_FALSE; - - mPreferredWidth = 0; - mPreferredHeight = 0; -} - -nsCommonWidget::~nsCommonWidget() -{ -} - -nsIWidget * -nsCommonWidget::GetParent(void) -{ - return mParent; -} - -void -nsCommonWidget::CommonCreate(nsIWidget *aParent, PRBool aListenForResizes) -{ - mParent = aParent; - mListenForResizes = aListenForResizes; - mCreated = PR_TRUE; -} - -void -nsCommonWidget::InitKeyEvent(nsKeyEvent &aEvent, GdkEventKey *aGdkEvent) -{ - aEvent.keyCode = GdkKeyCodeToDOMKeyCode(aGdkEvent->keyval); - aEvent.isShift = (aGdkEvent->state & GDK_SHIFT_MASK) - ? PR_TRUE : PR_FALSE; - aEvent.isControl = (aGdkEvent->state & GDK_CONTROL_MASK) - ? PR_TRUE : PR_FALSE; - aEvent.isAlt = (aGdkEvent->state & GDK_MOD1_MASK) - ? PR_TRUE : PR_FALSE; - aEvent.isMeta = (aGdkEvent->state & GDK_MOD4_MASK) - ? PR_TRUE : PR_FALSE; - // The transformations above and in gdk for the keyval are not invertible - // so link to the GdkEvent (which will vanish soon after return from the - // event callback) to give plugins access to hardware_keycode and state. - // (An XEvent would be nice but the GdkEvent is good enough.) - aEvent.nativeMsg = (void *)aGdkEvent; - - aEvent.time = aGdkEvent->time; -} - -void -nsCommonWidget::DispatchGotFocusEvent(void) -{ - nsGUIEvent event(PR_TRUE, NS_GOTFOCUS, this); - nsEventStatus status; - DispatchEvent(&event, status); -} - -void -nsCommonWidget::DispatchLostFocusEvent(void) -{ - nsGUIEvent event(PR_TRUE, NS_LOSTFOCUS, this); - nsEventStatus status; - DispatchEvent(&event, status); -} - -void -nsCommonWidget::DispatchActivateEvent(void) -{ - nsGUIEvent event(PR_TRUE, NS_ACTIVATE, this); - nsEventStatus status; - DispatchEvent(&event, status); -} - -void -nsCommonWidget::DispatchDeactivateEvent(void) -{ - nsGUIEvent event(PR_TRUE, NS_DEACTIVATE, this); - nsEventStatus status; - DispatchEvent(&event, status); -} - -void -nsCommonWidget::DispatchResizeEvent(nsRect &aRect, nsEventStatus &aStatus) -{ - nsSizeEvent event(PR_TRUE, NS_SIZE, this); - - event.windowSize = &aRect; - event.refPoint.x = aRect.x; - event.refPoint.y = aRect.y; - event.mWinWidth = aRect.width; - event.mWinHeight = aRect.height; - - nsEventStatus status; - DispatchEvent(&event, status); -} - -NS_IMETHODIMP -nsCommonWidget::DispatchEvent(nsGUIEvent *aEvent, - nsEventStatus &aStatus) -{ -#ifdef DEBUG - debug_DumpEvent(stdout, aEvent->widget, aEvent, - nsCAutoString("something"), 0); -#endif - - aStatus = nsEventStatus_eIgnore; - - // send it to the standard callback - if (mEventCallback) - aStatus = (* mEventCallback)(aEvent); - - // dispatch to event listener if event was not consumed - if ((aStatus != nsEventStatus_eIgnore) && mEventListener) - aStatus = mEventListener->ProcessEvent(*aEvent); - - return NS_OK; -} - -NS_IMETHODIMP -nsCommonWidget::Show(PRBool aState) -{ - mIsShown = aState; - - LOG(("nsCommonWidget::Show [%p] state %d\n", (void *)this, aState)); - - // Ok, someone called show on a window that isn't sized to a sane - // value. Mark this window as needing to have Show() called on it - // and return. - if ((aState && !AreBoundsSane()) || !mCreated) { - LOG(("\tbounds are insane or window hasn't been created yet\n")); - mNeedsShow = PR_TRUE; - return NS_OK; - } - - // If someone is hiding this widget, clear any needing show flag. - if (!aState) - mNeedsShow = PR_FALSE; - - // If someone is showing this window and it needs a resize then - // resize the widget. - if (aState) { - if (mNeedsMove) { - LOG(("\tresizing\n")); - NativeResize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, - PR_FALSE); - } else if (mNeedsResize) { - NativeResize(mBounds.width, mBounds.height, PR_FALSE); - } - } - - NativeShow(aState); - - return NS_OK; -} - -NS_IMETHODIMP -nsCommonWidget::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint) -{ - mBounds.SizeTo(GetSafeWindowSize(nsSize(aWidth, aHeight))); - - if (!mCreated) - return NS_OK; - - // There are several cases here that we need to handle, based on a - // matrix of the visibility of the widget, the sanity of this resize - // and whether or not the widget was previously sane. - - // Has this widget been set to visible? - if (mIsShown) { - // Are the bounds sane? - if (AreBoundsSane()) { - // Yep? Resize the window - //Maybe, the toplevel has moved - - // Note that if the widget needs to be shown because it - // was previously insane in Resize(x,y,w,h), then we need - // to set the x and y here too, because the widget wasn't - // moved back then - if (mIsTopLevel || mNeedsShow) - NativeResize(mBounds.x, mBounds.y, - mBounds.width, mBounds.height, aRepaint); - else - NativeResize(mBounds.width, mBounds.height, aRepaint); - - // Does it need to be shown because it was previously insane? - if (mNeedsShow) - NativeShow(PR_TRUE); - } - else { - // If someone has set this so that the needs show flag is false - // and it needs to be hidden, update the flag and hide the - // window. This flag will be cleared the next time someone - // hides the window or shows it. It also prevents us from - // calling NativeShow(PR_FALSE) excessively on the window which - // causes unneeded X traffic. - if (!mNeedsShow) { - mNeedsShow = PR_TRUE; - NativeShow(PR_FALSE); - } - } - } - // If the widget hasn't been shown, mark the widget as needing to be - // resized before it is shown. - else { - if (AreBoundsSane() && mListenForResizes) { - // For widgets that we listen for resizes for (widgets created - // with native parents) we apparently _always_ have to resize. I - // dunno why, but apparently we're lame like that. - NativeResize(aWidth, aHeight, aRepaint); - } - else { - mNeedsResize = PR_TRUE; - } - } - - // synthesize a resize event if this isn't a toplevel - if (mIsTopLevel || mListenForResizes) { - nsRect rect(mBounds.x, mBounds.y, aWidth, aHeight); - nsEventStatus status; - DispatchResizeEvent(rect, status); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsCommonWidget::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, - PRBool aRepaint) -{ - mBounds.x = aX; - mBounds.y = aY; - mBounds.SizeTo(GetSafeWindowSize(nsSize(aWidth, aHeight))); - - mPlaced = PR_TRUE; - - if (!mCreated) - return NS_OK; - - // There are several cases here that we need to handle, based on a - // matrix of the visibility of the widget, the sanity of this resize - // and whether or not the widget was previously sane. - - // Has this widget been set to visible? - if (mIsShown) { - // Are the bounds sane? - if (AreBoundsSane()) { - // Yep? Resize the window - NativeResize(aX, aY, aWidth, aHeight, aRepaint); - // Does it need to be shown because it was previously insane? - if (mNeedsShow) - NativeShow(PR_TRUE); - } - else { - // If someone has set this so that the needs show flag is false - // and it needs to be hidden, update the flag and hide the - // window. This flag will be cleared the next time someone - // hides the window or shows it. It also prevents us from - // calling NativeShow(PR_FALSE) excessively on the window which - // causes unneeded X traffic. - if (!mNeedsShow) { - mNeedsShow = PR_TRUE; - NativeShow(PR_FALSE); - } - } - } - // If the widget hasn't been shown, mark the widget as needing to be - // resized before it is shown - else { - if (AreBoundsSane() && mListenForResizes){ - // For widgets that we listen for resizes for (widgets created - // with native parents) we apparently _always_ have to resize. I - // dunno why, but apparently we're lame like that. - NativeResize(aX, aY, aWidth, aHeight, aRepaint); - } - else { - mNeedsResize = PR_TRUE; - mNeedsMove = PR_TRUE; - } - } - - if (mIsTopLevel || mListenForResizes) { - // synthesize a resize event - nsRect rect(aX, aY, aWidth, aHeight); - nsEventStatus status; - DispatchResizeEvent(rect, status); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsCommonWidget::GetPreferredSize(PRInt32 &aWidth, - PRInt32 &aHeight) -{ - aWidth = mPreferredWidth; - aHeight = mPreferredHeight; - return (mPreferredWidth != 0 && mPreferredHeight != 0) ? - NS_OK : NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -nsCommonWidget::SetPreferredSize(PRInt32 aWidth, - PRInt32 aHeight) -{ - mPreferredWidth = aWidth; - mPreferredHeight = aHeight; - return NS_OK; -} - -NS_IMETHODIMP -nsCommonWidget::Enable(PRBool aState) -{ - mEnabled = aState; - - return NS_OK; -} - -NS_IMETHODIMP -nsCommonWidget::IsEnabled(PRBool *aState) -{ - *aState = mEnabled; - - return NS_OK; -} - -void -nsCommonWidget::OnDestroy(void) -{ - if (mOnDestroyCalled) - return; - - mOnDestroyCalled = PR_TRUE; - - // release references to children, device context, toolkit + app shell - nsBaseWidget::OnDestroy(); - - // let go of our parent - mParent = nsnull; - - nsCOMPtr kungFuDeathGrip = this; - - nsGUIEvent event(PR_TRUE, NS_DESTROY, this); - nsEventStatus status; - DispatchEvent(&event, status); -} - -PRBool -nsCommonWidget::AreBoundsSane(void) -{ - if (mBounds.width > 0 && mBounds.height > 0) - return PR_TRUE; - - return PR_FALSE; -} diff --git a/widget/src/gtk2/nsCommonWidget.h b/widget/src/gtk2/nsCommonWidget.h deleted file mode 100644 index 15a1efb849d..00000000000 --- a/widget/src/gtk2/nsCommonWidget.h +++ /dev/null @@ -1,161 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:expandtab:shiftwidth=4:tabstop=4: - */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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.org code. - * - * The Initial Developer of the Original Code is Christopher Blizzard - * . Portions created by the Initial Developer - * are Copyright (C) 2001 the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __nsCommonWidget_h__ -#define __nsCommonWidget_h__ - -#include "nsBaseWidget.h" -#include "nsGUIEvent.h" -#include - -#ifdef MOZ_LOGGING - -// make sure that logging is enabled before including prlog.h -#define FORCE_PR_LOG - -#include "prlog.h" - -extern PRLogModuleInfo *gWidgetLog; -extern PRLogModuleInfo *gWidgetFocusLog; -extern PRLogModuleInfo *gWidgetIMLog; -extern PRLogModuleInfo *gWidgetDrawLog; - -#define LOG(args) PR_LOG(gWidgetLog, 4, args) -#define LOGFOCUS(args) PR_LOG(gWidgetFocusLog, 4, args) -#define LOGIM(args) PR_LOG(gWidgetIMLog, 4, args) -#define LOGDRAW(args) PR_LOG(gWidgetDrawLog, 4, args) - -#else - -#define LOG(args) -#define LOGFOCUS(args) -#define LOGIM(args) -#define LOGDRAW(args) - -#endif /* MOZ_LOGGING */ - -class nsCommonWidget : public nsBaseWidget { -public: - nsCommonWidget(); - virtual ~nsCommonWidget(); - - virtual nsIWidget *GetParent(void); - - void CommonCreate(nsIWidget *aParent, PRBool aListenForResizes); - - // event handling code - void InitKeyEvent(nsKeyEvent &aEvent, GdkEventKey *aGdkEvent); - - void DispatchGotFocusEvent(void); - void DispatchLostFocusEvent(void); - void DispatchActivateEvent(void); - void DispatchDeactivateEvent(void); - void DispatchResizeEvent(nsRect &aRect, nsEventStatus &aStatus); - - NS_IMETHOD DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus); - - // virtual interfaces for some nsIWidget methods - virtual void NativeResize(PRInt32 aWidth, - PRInt32 aHeight, - PRBool aRepaint) = 0; - - virtual void NativeResize(PRInt32 aX, - PRInt32 aY, - PRInt32 aWidth, - PRInt32 aHeight, - PRBool aRepaint) = 0; - - virtual void NativeShow (PRBool aAction) = 0; - - virtual nsSize GetSafeWindowSize(nsSize aSize) = 0; - - // Some of the nsIWidget methods - NS_IMETHOD Show (PRBool aState); - NS_IMETHOD Resize (PRInt32 aWidth, - PRInt32 aHeight, - PRBool aRepaint); - NS_IMETHOD Resize (PRInt32 aX, - PRInt32 aY, - PRInt32 aWidth, - PRInt32 aHeight, - PRBool aRepaint); - NS_IMETHOD GetPreferredSize (PRInt32 &aWidth, - PRInt32 &aHeight); - NS_IMETHOD SetPreferredSize (PRInt32 aWidth, - PRInt32 aHeight); - NS_IMETHOD Enable (PRBool aState); - NS_IMETHOD IsEnabled (PRBool *aState); - - // called when we are destroyed - void OnDestroy(void); - - // called to check and see if a widget's dimensions are sane - PRBool AreBoundsSane(void); - -protected: - nsCOMPtr mParent; - // Is this a toplevel window? - PRPackedBool mIsTopLevel; - // Has this widget been destroyed yet? - PRPackedBool mIsDestroyed; - - // This is a flag that tracks if we need to resize a widget or - // window when we show it. - PRPackedBool mNeedsResize; - // This is a flag that tracks if we need to move a widget or - // window when we show it. - PRPackedBool mNeedsMove; - // Should we send resize events on all resizes? - PRPackedBool mListenForResizes; - // This flag tracks if we're hidden or shown. - PRPackedBool mIsShown; - PRPackedBool mNeedsShow; - // is this widget enabled? - PRBool mEnabled; - // has the native window for this been created yet? - PRBool mCreated; - // Has anyone set an x/y location for this widget yet? Toplevels - // shouldn't be automatically set to 0,0 for first show. - PRBool mPlaced; - - // Preferred sizes - PRUint32 mPreferredWidth; - PRUint32 mPreferredHeight; -}; - -#endif /* __nsCommonWidget_h__ */ diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp index 9bb3bc26f20..c8b59f3cd1a 100644 --- a/widget/src/gtk2/nsWindow.cpp +++ b/widget/src/gtk2/nsWindow.cpp @@ -350,6 +350,19 @@ static PRBool gForce24bpp = PR_FALSE; nsWindow::nsWindow() { + mIsTopLevel = PR_FALSE; + mIsDestroyed = PR_FALSE; + mNeedsResize = PR_FALSE; + mNeedsMove = PR_FALSE; + mListenForResizes = PR_FALSE; + mIsShown = PR_FALSE; + mNeedsShow = PR_FALSE; + mEnabled = PR_TRUE; + mCreated = PR_FALSE; + mPlaced = PR_FALSE; + + mPreferredWidth = 0; + mPreferredHeight = 0; mContainer = nsnull; mDrawingarea = nsnull; mShell = nsnull; @@ -455,9 +468,147 @@ nsWindow::ReleaseGlobals() } } -NS_IMPL_ISUPPORTS_INHERITED1(nsWindow, nsCommonWidget, +NS_IMPL_ISUPPORTS_INHERITED1(nsWindow, nsBaseWidget, nsISupportsWeakReference) +void +nsWindow::CommonCreate(nsIWidget *aParent, PRBool aListenForResizes) +{ + mParent = aParent; + mListenForResizes = aListenForResizes; + mCreated = PR_TRUE; +} + +void +nsWindow::InitKeyEvent(nsKeyEvent &aEvent, GdkEventKey *aGdkEvent) +{ + aEvent.keyCode = GdkKeyCodeToDOMKeyCode(aGdkEvent->keyval); + aEvent.isShift = (aGdkEvent->state & GDK_SHIFT_MASK) + ? PR_TRUE : PR_FALSE; + aEvent.isControl = (aGdkEvent->state & GDK_CONTROL_MASK) + ? PR_TRUE : PR_FALSE; + aEvent.isAlt = (aGdkEvent->state & GDK_MOD1_MASK) + ? PR_TRUE : PR_FALSE; + aEvent.isMeta = (aGdkEvent->state & GDK_MOD4_MASK) + ? PR_TRUE : PR_FALSE; + // The transformations above and in gdk for the keyval are not invertible + // so link to the GdkEvent (which will vanish soon after return from the + // event callback) to give plugins access to hardware_keycode and state. + // (An XEvent would be nice but the GdkEvent is good enough.) + aEvent.nativeMsg = (void *)aGdkEvent; + + aEvent.time = aGdkEvent->time; +} + +void +nsWindow::DispatchGotFocusEvent(void) +{ + nsGUIEvent event(PR_TRUE, NS_GOTFOCUS, this); + nsEventStatus status; + DispatchEvent(&event, status); +} + +void +nsWindow::DispatchLostFocusEvent(void) +{ + nsGUIEvent event(PR_TRUE, NS_LOSTFOCUS, this); + nsEventStatus status; + DispatchEvent(&event, status); +} + + +void +nsWindow::DispatchResizeEvent(nsRect &aRect, nsEventStatus &aStatus) +{ + nsSizeEvent event(PR_TRUE, NS_SIZE, this); + + event.windowSize = &aRect; + event.refPoint.x = aRect.x; + event.refPoint.y = aRect.y; + event.mWinWidth = aRect.width; + event.mWinHeight = aRect.height; + + nsEventStatus status; + DispatchEvent(&event, status); +} + +void +nsWindow::DispatchActivateEvent(void) +{ +#ifdef ACCESSIBILITY + DispatchActivateEventAccessible(); +#endif //ACCESSIBILITY + nsGUIEvent event(PR_TRUE, NS_ACTIVATE, this); + nsEventStatus status; + DispatchEvent(&event, status); +} + +void +nsWindow::DispatchDeactivateEvent(void) +{ + nsGUIEvent event(PR_TRUE, NS_DEACTIVATE, this); + nsEventStatus status; + DispatchEvent(&event, status); + +#ifdef ACCESSIBILITY + DispatchDeactivateEventAccessible(); +#endif //ACCESSIBILITY +} + + + +nsresult +nsWindow::DispatchEvent(nsGUIEvent *aEvent, + nsEventStatus &aStatus) +{ +#ifdef DEBUG + debug_DumpEvent(stdout, aEvent->widget, aEvent, + nsCAutoString("something"), 0); +#endif + + aStatus = nsEventStatus_eIgnore; + + // send it to the standard callback + if (mEventCallback) + aStatus = (* mEventCallback)(aEvent); + + // dispatch to event listener if event was not consumed + if ((aStatus != nsEventStatus_eIgnore) && mEventListener) + aStatus = mEventListener->ProcessEvent(*aEvent); + + return NS_OK; +} + +void +nsWindow::OnDestroy(void) +{ + if (mOnDestroyCalled) + return; + + mOnDestroyCalled = PR_TRUE; + + // release references to children, device context, toolkit + app shell + nsBaseWidget::OnDestroy(); + + // let go of our parent + mParent = nsnull; + + nsCOMPtr kungFuDeathGrip = this; + + nsGUIEvent event(PR_TRUE, NS_DESTROY, this); + nsEventStatus status; + DispatchEvent(&event, status); +} + +PRBool +nsWindow::AreBoundsSane(void) +{ + if (mBounds.width > 0 && mBounds.height > 0) + return PR_TRUE; + + return PR_FALSE; +} + NS_IMETHODIMP nsWindow::Create(nsIWidget *aParent, const nsRect &aRect, @@ -599,6 +750,12 @@ nsWindow::Destroy(void) return NS_OK; } +nsIWidget * +nsWindow::GetParent(void) +{ + return mParent; +} + NS_IMETHODIMP nsWindow::SetParent(nsIWidget *aNewParent) { @@ -698,6 +855,215 @@ nsWindow::ConstrainPosition(PRBool aAllowSlop, PRInt32 *aX, PRInt32 *aY) return NS_OK; } +NS_IMETHODIMP +nsWindow::Show(PRBool aState) +{ + mIsShown = aState; + + LOG(("nsWindow::Show [%p] state %d\n", (void *)this, aState)); + + // Ok, someone called show on a window that isn't sized to a sane + // value. Mark this window as needing to have Show() called on it + // and return. + if ((aState && !AreBoundsSane()) || !mCreated) { + LOG(("\tbounds are insane or window hasn't been created yet\n")); + mNeedsShow = PR_TRUE; + return NS_OK; + } + + // If someone is hiding this widget, clear any needing show flag. + if (!aState) + mNeedsShow = PR_FALSE; + + // If someone is showing this window and it needs a resize then + // resize the widget. + if (aState) { + if (mNeedsMove) { + LOG(("\tresizing\n")); + NativeResize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, + PR_FALSE); + } else if (mNeedsResize) { + NativeResize(mBounds.width, mBounds.height, PR_FALSE); + } + } + + NativeShow(aState); + + return NS_OK; +} + +NS_IMETHODIMP +nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint) +{ + mBounds.SizeTo(GetSafeWindowSize(nsSize(aWidth, aHeight))); + + if (!mCreated) + return NS_OK; + + // There are several cases here that we need to handle, based on a + // matrix of the visibility of the widget, the sanity of this resize + // and whether or not the widget was previously sane. + + // Has this widget been set to visible? + if (mIsShown) { + // Are the bounds sane? + if (AreBoundsSane()) { + // Yep? Resize the window + //Maybe, the toplevel has moved + + // Note that if the widget needs to be shown because it + // was previously insane in Resize(x,y,w,h), then we need + // to set the x and y here too, because the widget wasn't + // moved back then + if (mIsTopLevel || mNeedsShow) + NativeResize(mBounds.x, mBounds.y, + mBounds.width, mBounds.height, aRepaint); + else + NativeResize(mBounds.width, mBounds.height, aRepaint); + + // Does it need to be shown because it was previously insane? + if (mNeedsShow) + NativeShow(PR_TRUE); + } + else { + // If someone has set this so that the needs show flag is false + // and it needs to be hidden, update the flag and hide the + // window. This flag will be cleared the next time someone + // hides the window or shows it. It also prevents us from + // calling NativeShow(PR_FALSE) excessively on the window which + // causes unneeded X traffic. + if (!mNeedsShow) { + mNeedsShow = PR_TRUE; + NativeShow(PR_FALSE); + } + } + } + // If the widget hasn't been shown, mark the widget as needing to be + // resized before it is shown. + else { + if (AreBoundsSane() && mListenForResizes) { + // For widgets that we listen for resizes for (widgets created + // with native parents) we apparently _always_ have to resize. I + // dunno why, but apparently we're lame like that. + NativeResize(aWidth, aHeight, aRepaint); + } + else { + mNeedsResize = PR_TRUE; + } + } + + // synthesize a resize event if this isn't a toplevel + if (mIsTopLevel || mListenForResizes) { + nsRect rect(mBounds.x, mBounds.y, aWidth, aHeight); + nsEventStatus status; + DispatchResizeEvent(rect, status); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsWindow::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, + PRBool aRepaint) +{ + mBounds.x = aX; + mBounds.y = aY; + mBounds.SizeTo(GetSafeWindowSize(nsSize(aWidth, aHeight))); + + mPlaced = PR_TRUE; + + if (!mCreated) + return NS_OK; + + // There are several cases here that we need to handle, based on a + // matrix of the visibility of the widget, the sanity of this resize + // and whether or not the widget was previously sane. + + // Has this widget been set to visible? + if (mIsShown) { + // Are the bounds sane? + if (AreBoundsSane()) { + // Yep? Resize the window + NativeResize(aX, aY, aWidth, aHeight, aRepaint); + // Does it need to be shown because it was previously insane? + if (mNeedsShow) + NativeShow(PR_TRUE); + } + else { + // If someone has set this so that the needs show flag is false + // and it needs to be hidden, update the flag and hide the + // window. This flag will be cleared the next time someone + // hides the window or shows it. It also prevents us from + // calling NativeShow(PR_FALSE) excessively on the window which + // causes unneeded X traffic. + if (!mNeedsShow) { + mNeedsShow = PR_TRUE; + NativeShow(PR_FALSE); + } + } + } + // If the widget hasn't been shown, mark the widget as needing to be + // resized before it is shown + else { + if (AreBoundsSane() && mListenForResizes){ + // For widgets that we listen for resizes for (widgets created + // with native parents) we apparently _always_ have to resize. I + // dunno why, but apparently we're lame like that. + NativeResize(aX, aY, aWidth, aHeight, aRepaint); + } + else { + mNeedsResize = PR_TRUE; + mNeedsMove = PR_TRUE; + } + } + + if (mIsTopLevel || mListenForResizes) { + // synthesize a resize event + nsRect rect(aX, aY, aWidth, aHeight); + nsEventStatus status; + DispatchResizeEvent(rect, status); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsWindow::GetPreferredSize(PRInt32 &aWidth, + PRInt32 &aHeight) +{ + aWidth = mPreferredWidth; + aHeight = mPreferredHeight; + return (mPreferredWidth != 0 && mPreferredHeight != 0) ? + NS_OK : NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsWindow::SetPreferredSize(PRInt32 aWidth, + PRInt32 aHeight) +{ + mPreferredWidth = aWidth; + mPreferredHeight = aHeight; + return NS_OK; +} + +NS_IMETHODIMP +nsWindow::Enable(PRBool aState) +{ + mEnabled = aState; + + return NS_OK; +} + +NS_IMETHODIMP +nsWindow::IsEnabled(PRBool *aState) +{ + *aState = mEnabled; + + return NS_OK; +} + + + NS_IMETHODIMP nsWindow::Move(PRInt32 aX, PRInt32 aY) { @@ -807,12 +1173,6 @@ nsWindow::SetSizeMode(PRInt32 aMode) return rv; } -NS_IMETHODIMP -nsWindow::Enable(PRBool aState) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - typedef void (* SetUserTimeFunc)(GdkWindow* aWindow, guint32 aTimestamp); // This will become obsolete when new GTK APIs are widely supported, @@ -5634,7 +5994,7 @@ nsWindow::DispatchAccessibleEvent(nsIAccessible** aAccessible) } void -nsWindow::DispatchActivateEvent(void) +nsWindow::DispatchActivateEventAccessible(void) { if (sAccessibilityEnabled) { nsCOMPtr rootAcc; @@ -5646,15 +6006,11 @@ nsWindow::DispatchActivateEvent(void) rootAcc); } } - - nsCommonWidget::DispatchActivateEvent(); } void -nsWindow::DispatchDeactivateEvent(void) +nsWindow::DispatchDeactivateEventAccessible(void) { - nsCommonWidget::DispatchDeactivateEvent(); - if (sAccessibilityEnabled) { nsCOMPtr rootAcc; GetRootAccessible(getter_AddRefs(rootAcc)); @@ -5666,6 +6022,7 @@ nsWindow::DispatchDeactivateEvent(void) } } } + #endif /* #ifdef ACCESSIBILITY */ // nsChildWindow class diff --git a/widget/src/gtk2/nsWindow.h b/widget/src/gtk2/nsWindow.h index 32773fc390e..6647fd063f7 100644 --- a/widget/src/gtk2/nsWindow.h +++ b/widget/src/gtk2/nsWindow.h @@ -42,8 +42,6 @@ #include "nsAutoPtr.h" -#include "nsCommonWidget.h" - #include "mozcontainer.h" #include "mozdrawingarea.h" #include "nsWeakReference.h" @@ -54,6 +52,9 @@ #include "gfxASurface.h" +#include "nsBaseWidget.h" +#include "nsGUIEvent.h" +#include #include #ifdef MOZ_DFB @@ -75,7 +76,34 @@ #include "pldhash.h" #endif -class nsWindow : public nsCommonWidget, public nsSupportsWeakReference +#ifdef MOZ_LOGGING + +// make sure that logging is enabled before including prlog.h +#define FORCE_PR_LOG + +#include "prlog.h" + +extern PRLogModuleInfo *gWidgetLog; +extern PRLogModuleInfo *gWidgetFocusLog; +extern PRLogModuleInfo *gWidgetIMLog; +extern PRLogModuleInfo *gWidgetDrawLog; + +#define LOG(args) PR_LOG(gWidgetLog, 4, args) +#define LOGFOCUS(args) PR_LOG(gWidgetFocusLog, 4, args) +#define LOGIM(args) PR_LOG(gWidgetIMLog, 4, args) +#define LOGDRAW(args) PR_LOG(gWidgetDrawLog, 4, args) + +#else + +#define LOG(args) +#define LOGFOCUS(args) +#define LOGIM(args) +#define LOGDRAW(args) + +#endif /* MOZ_LOGGING */ + + +class nsWindow : public nsBaseWidget, public nsSupportsWeakReference { public: nsWindow(); @@ -84,6 +112,25 @@ public: static void ReleaseGlobals(); NS_DECL_ISUPPORTS_INHERITED + + void CommonCreate(nsIWidget *aParent, PRBool aListenForResizes); + + // event handling code + void InitKeyEvent(nsKeyEvent &aEvent, GdkEventKey *aGdkEvent); + + void DispatchGotFocusEvent(void); + void DispatchLostFocusEvent(void); + void DispatchActivateEvent(void); + void DispatchDeactivateEvent(void); + void DispatchResizeEvent(nsRect &aRect, nsEventStatus &aStatus); + + virtual nsresult DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus); + + // called when we are destroyed + void OnDestroy(void); + + // called to check and see if a widget's dimensions are sane + PRBool AreBoundsSane(void); // nsIWidget NS_IMETHOD Create(nsIWidget *aParent, @@ -101,7 +148,8 @@ public: nsIToolkit *aToolkit, nsWidgetInitData *aInitData); NS_IMETHOD Destroy(void); - NS_IMETHOD SetParent(nsIWidget* aNewParent); + virtual nsIWidget *GetParent(); + virtual nsresult SetParent(nsIWidget* aNewParent); NS_IMETHOD SetModal(PRBool aModal); NS_IMETHOD IsVisible(PRBool & aState); NS_IMETHOD ConstrainPosition(PRBool aAllowSlop, @@ -109,6 +157,22 @@ public: PRInt32 *aY); NS_IMETHOD Move(PRInt32 aX, PRInt32 aY); + NS_IMETHOD Show (PRBool aState); + NS_IMETHOD Resize (PRInt32 aWidth, + PRInt32 aHeight, + PRBool aRepaint); + NS_IMETHOD Resize (PRInt32 aX, + PRInt32 aY, + PRInt32 aWidth, + PRInt32 aHeight, + PRBool aRepaint); + NS_IMETHOD GetPreferredSize (PRInt32 &aWidth, + PRInt32 &aHeight); + NS_IMETHOD SetPreferredSize (PRInt32 aWidth, + PRInt32 aHeight); + NS_IMETHOD IsEnabled (PRBool *aState); + + NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, nsIWidget *aWidget, PRBool aActivate); @@ -237,17 +301,17 @@ public: nsIToolkit *aToolkit, nsWidgetInitData *aInitData); - void NativeResize(PRInt32 aWidth, + virtual void NativeResize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint); - void NativeResize(PRInt32 aX, + virtual void NativeResize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint); - void NativeShow (PRBool aAction); + virtual void NativeShow (PRBool aAction); virtual nsSize GetSafeWindowSize(nsSize aSize); void EnsureGrabs (void); @@ -379,6 +443,35 @@ public: #ifdef ACCESSIBILITY static PRBool sAccessibilityEnabled; #endif +protected: + nsCOMPtr mParent; + // Is this a toplevel window? + PRPackedBool mIsTopLevel; + // Has this widget been destroyed yet? + PRPackedBool mIsDestroyed; + + // This is a flag that tracks if we need to resize a widget or + // window when we show it. + PRPackedBool mNeedsResize; + // This is a flag that tracks if we need to move a widget or + // window when we show it. + PRPackedBool mNeedsMove; + // Should we send resize events on all resizes? + PRPackedBool mListenForResizes; + // This flag tracks if we're hidden or shown. + PRPackedBool mIsShown; + PRPackedBool mNeedsShow; + // is this widget enabled? + PRPackedBool mEnabled; + // has the native window for this been created yet? + PRPackedBool mCreated; + // Has anyone set an x/y location for this widget yet? Toplevels + // shouldn't be automatically set to 0,0 for first show. + PRPackedBool mPlaced; + + // Preferred sizes + PRUint32 mPreferredWidth; + PRUint32 mPreferredHeight; private: void GetToplevelWidget(GtkWidget **aWidget); @@ -425,8 +518,8 @@ private: nsCOMPtr mRootAccessible; void CreateRootAccessible(); void GetRootAccessible(nsIAccessible** aAccessible); - void DispatchActivateEvent(void); - void DispatchDeactivateEvent(void); + void DispatchActivateEventAccessible(); + void DispatchDeactivateEventAccessible(); NS_IMETHOD_(PRBool) DispatchAccessibleEvent(nsIAccessible** aAccessible); #endif