Bug 126592. GTK1 widgets are limited to 16-bit coordinates, so hack around their limitations by hiding widgets which are completely scrolled offscreen (so they don't wrap back onscreen)

This commit is contained in:
roc+%cs.cmu.edu 2003-01-17 00:27:13 +00:00
Родитель 8c133355e7
Коммит e99361923b
4 изменённых файлов: 117 добавлений и 20 удалений

Просмотреть файл

@ -224,6 +224,7 @@ nsWidget::nsWidget()
mPreferredWidth = 0; mPreferredWidth = 0;
mPreferredHeight = 0; mPreferredHeight = 0;
mShown = PR_FALSE; mShown = PR_FALSE;
mInternalShown = PR_FALSE;
mBounds.x = 0; mBounds.x = 0;
mBounds.y = 0; mBounds.y = 0;
mBounds.width = 0; mBounds.width = 0;
@ -438,20 +439,52 @@ NS_IMETHODIMP nsWidget::Show(PRBool bState)
if (!mWidget) if (!mWidget)
return NS_OK; // Will be null durring printing return NS_OK; // Will be null durring printing
if (bState) {
gtk_widget_show(mWidget);
gtk_widget_show(mMozBox);
}
else {
gtk_widget_hide(mMozBox);
gtk_widget_hide(mWidget);
}
mShown = bState; mShown = bState;
ResetInternalVisibility();
return NS_OK; return NS_OK;
} }
void nsWidget::ResetInternalVisibility()
{
PRBool show = mShown;
if (show) {
if (mParent != nsnull) {
nsRect parentBounds;
mParent->GetClientBounds(parentBounds);
parentBounds.x = parentBounds.y = 0;
nsRect myBounds;
GetBounds(myBounds);
if (!myBounds.Intersects(parentBounds)) {
show = PR_FALSE;
}
}
}
if (show == mInternalShown) {
return;
}
SetInternalVisibility(show);
}
void nsWidget::SetInternalVisibility(PRBool aVisible)
{
mInternalShown = aVisible;
if (aVisible) {
if (mWidget)
gtk_widget_show(mWidget);
if (mMozBox)
gtk_widget_show(mMozBox);
} else {
if (mWidget)
gtk_widget_hide(mWidget);
if (mMozBox)
gtk_widget_hide(mMozBox);
}
}
NS_IMETHODIMP nsWidget::CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent) NS_IMETHODIMP nsWidget::CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent)
{ {
@ -548,12 +581,13 @@ NS_IMETHODIMP nsWidget::Move(PRInt32 aX, PRInt32 aY)
mBounds.x = aX; mBounds.x = aX;
mBounds.y = aY; mBounds.y = aY;
if (mMozBox) if (mMozBox)
{ {
gtk_mozbox_set_position(GTK_MOZBOX(mMozBox), aX, aY); gtk_mozbox_set_position(GTK_MOZBOX(mMozBox), aX, aY);
} }
ResetInternalVisibility();
return NS_OK; return NS_OK;
} }
@ -571,6 +605,17 @@ NS_IMETHODIMP nsWidget::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
if (mWidget) if (mWidget)
gtk_widget_set_usize(mWidget, aWidth, aHeight); gtk_widget_set_usize(mWidget, aWidth, aHeight);
ResetInternalVisibility();
PRUint32 childCount, index;
if (NS_SUCCEEDED(mChildren->Count(&childCount))) {
for (index = 0; index < childCount; index++) {
nsCOMPtr<nsIWidget> childWidget;
if (NS_SUCCEEDED(mChildren->QueryElementAt(index, NS_GET_IID(nsIWidget), (void**)getter_AddRefs(childWidget)))) {
NS_STATIC_CAST(nsWidget*, NS_STATIC_CAST(nsIWidget*, childWidget.get()))->ResetInternalVisibility();
}
}
}
return NS_OK; return NS_OK;
} }
@ -615,6 +660,8 @@ PRBool nsWidget::OnResize(nsRect &aRect)
mBounds.width = aRect.width; mBounds.width = aRect.width;
mBounds.height = aRect.height; mBounds.height = aRect.height;
ResetInternalVisibility();
NS_ADDREF_THIS(); NS_ADDREF_THIS();
PRBool result = OnResize(&event); PRBool result = OnResize(&event);
NS_RELEASE_THIS(); NS_RELEASE_THIS();
@ -636,6 +683,8 @@ PRBool nsWidget::OnMove(PRInt32 aX, PRInt32 aY)
mBounds.x = aX; mBounds.x = aX;
mBounds.y = aY; mBounds.y = aY;
ResetInternalVisibility();
nsGUIEvent event; nsGUIEvent event;
InitEvent(event, NS_MOVE); InitEvent(event, NS_MOVE);
event.point.x = aX; event.point.x = aX;

Просмотреть файл

@ -308,7 +308,18 @@ protected:
public: public:
virtual void IMECommitEvent(GdkEventKey *aEvent); virtual void IMECommitEvent(GdkEventKey *aEvent);
// This MUST be called after you change the widget bounds
// or after the parent's size changes
// or when you show the widget
// We will decide whether to really show the widget or not
// We will hide the widget if it doesn't overlap the parent bounds
// This reduces problems with 16-bit coordinates wrapping.
virtual void ResetInternalVisibility();
protected: protected:
// override this method to do whatever you have to do to make this widget
// visible or invisibile --- i.e., the real work of Show()
virtual void SetInternalVisibility(PRBool aVisible);
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// //
@ -376,10 +387,10 @@ protected:
// Invalidate) // Invalidate)
nsCOMPtr<nsIRegion> mUpdateArea; nsCOMPtr<nsIRegion> mUpdateArea;
PRBool mShown;
PRUint32 mPreferredWidth, mPreferredHeight; PRUint32 mPreferredWidth, mPreferredHeight;
PRBool mListenForResizes; PRPackedBool mListenForResizes;
PRPackedBool mShown;
PRPackedBool mInternalShown;
// this is the rollup listener variables // this is the rollup listener variables
static nsCOMPtr<nsIRollupListener> gRollupListener; static nsCOMPtr<nsIRollupListener> gRollupListener;

Просмотреть файл

@ -2297,7 +2297,9 @@ NS_IMETHODIMP nsWindow::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
child->GetBounds(bounds); child->GetBounds(bounds);
bounds.x += aDx; bounds.x += aDx;
bounds.y += aDy; bounds.y += aDy;
NS_STATIC_CAST(nsBaseWidget*, (nsIWidget*)child)->SetBounds(bounds); nsWidget* childWidget = NS_STATIC_CAST(nsWidget*, NS_STATIC_CAST(nsIWidget*, child.get()));
childWidget->SetBounds(bounds);
childWidget->ResetInternalVisibility();
} }
if (NS_FAILED(children->Next())) if (NS_FAILED(children->Next()))
@ -2561,13 +2563,33 @@ NS_IMETHODIMP nsWindow::Show(PRBool bState)
mShown = bState; mShown = bState;
// show
ResetInternalVisibility();
return NS_OK;
}
void nsWindow::ResetInternalVisibility()
{
if (mShell)
{ // top level, always set the visibility regardless of parent geometry
SetInternalVisibility(mShown);
}
else
{
nsWidget::ResetInternalVisibility();
}
}
void nsWindow::SetInternalVisibility(PRBool aVisible)
{
// don't show if we are too small // don't show if we are too small
if (mIsTooSmall) if (mIsTooSmall)
return NS_OK; return;
// show mInternalShown = aVisible;
if (bState)
if (aVisible)
{ {
// show mSuperWin // show mSuperWin
gdk_window_show(mSuperWin->bin_window); gdk_window_show(mSuperWin->bin_window);
@ -2601,8 +2623,6 @@ NS_IMETHODIMP nsWindow::Show(PRBool bState)
} }
} }
return NS_OK;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -2688,6 +2708,8 @@ NS_IMETHODIMP nsWindow::Move(PRInt32 aX, PRInt32 aY)
mBounds.x = aX; mBounds.x = aX;
mBounds.y = aY; mBounds.y = aY;
ResetInternalVisibility();
if (mIsToplevel && mShell) if (mIsToplevel && mShell)
{ {
#ifdef DEBUG #ifdef DEBUG
@ -2736,6 +2758,17 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
mBounds.width = aWidth; mBounds.width = aWidth;
mBounds.height = aHeight; mBounds.height = aHeight;
ResetInternalVisibility();
PRUint32 childCount, index;
if (NS_SUCCEEDED(mChildren->Count(&childCount))) {
for (index = 0; index < childCount; index++) {
nsCOMPtr<nsIWidget> childWidget;
if (NS_SUCCEEDED(mChildren->QueryElementAt(index, NS_GET_IID(nsIWidget), (void**)getter_AddRefs(childWidget)))) {
NS_STATIC_CAST(nsWidget*, NS_STATIC_CAST(nsIWidget*, childWidget.get()))->ResetInternalVisibility();
}
}
}
// code to keep the window from showing before it has been moved or resized // code to keep the window from showing before it has been moved or resized
// if we are resized to 1x1 or less, we will hide the window. Show(TRUE) will be ignored until a // if we are resized to 1x1 or less, we will hide the window. Show(TRUE) will be ignored until a
@ -2773,6 +2806,7 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
gdk_window_hide(mSuperWin->bin_window); gdk_window_hide(mSuperWin->bin_window);
gdk_window_hide(mSuperWin->shell_window); gdk_window_hide(mSuperWin->shell_window);
} }
mInternalShown = PR_FALSE;
} }
else else
{ {
@ -2823,8 +2857,9 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
//g_print("not sending resize event\n"); //g_print("not sending resize event\n");
} }
if (nNeedToShow) if (nNeedToShow) {
Show(PR_TRUE); Show(PR_TRUE);
}
if (aRepaint) if (aRepaint)
Invalidate(PR_FALSE); Invalidate(PR_FALSE);

Просмотреть файл

@ -198,6 +198,8 @@ public:
static void ClearIconEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr); static void ClearIconEntry(PLDHashTable* aTable, PLDHashEntryHdr* aHdr);
protected: protected:
virtual void ResetInternalVisibility();
virtual void SetInternalVisibility(PRBool aVisible);
virtual void OnRealize(GtkWidget *aWidget); virtual void OnRealize(GtkWidget *aWidget);