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
Родитель 4026d7da7e
Коммит 7128e98adb
4 изменённых файлов: 117 добавлений и 20 удалений

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

@ -224,6 +224,7 @@ nsWidget::nsWidget()
mPreferredWidth = 0;
mPreferredHeight = 0;
mShown = PR_FALSE;
mInternalShown = PR_FALSE;
mBounds.x = 0;
mBounds.y = 0;
mBounds.width = 0;
@ -438,20 +439,52 @@ NS_IMETHODIMP nsWidget::Show(PRBool bState)
if (!mWidget)
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;
ResetInternalVisibility();
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)
{
@ -548,12 +581,13 @@ NS_IMETHODIMP nsWidget::Move(PRInt32 aX, PRInt32 aY)
mBounds.x = aX;
mBounds.y = aY;
if (mMozBox)
{
gtk_mozbox_set_position(GTK_MOZBOX(mMozBox), aX, aY);
}
ResetInternalVisibility();
return NS_OK;
}
@ -571,6 +605,17 @@ NS_IMETHODIMP nsWidget::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
if (mWidget)
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;
}
@ -615,6 +660,8 @@ PRBool nsWidget::OnResize(nsRect &aRect)
mBounds.width = aRect.width;
mBounds.height = aRect.height;
ResetInternalVisibility();
NS_ADDREF_THIS();
PRBool result = OnResize(&event);
NS_RELEASE_THIS();
@ -636,6 +683,8 @@ PRBool nsWidget::OnMove(PRInt32 aX, PRInt32 aY)
mBounds.x = aX;
mBounds.y = aY;
ResetInternalVisibility();
nsGUIEvent event;
InitEvent(event, NS_MOVE);
event.point.x = aX;

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

@ -308,7 +308,18 @@ protected:
public:
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:
// 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)
nsCOMPtr<nsIRegion> mUpdateArea;
PRBool mShown;
PRUint32 mPreferredWidth, mPreferredHeight;
PRBool mListenForResizes;
PRPackedBool mListenForResizes;
PRPackedBool mShown;
PRPackedBool mInternalShown;
// this is the rollup listener variables
static nsCOMPtr<nsIRollupListener> gRollupListener;

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

@ -2297,7 +2297,9 @@ NS_IMETHODIMP nsWindow::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect)
child->GetBounds(bounds);
bounds.x += aDx;
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()))
@ -2561,13 +2563,33 @@ NS_IMETHODIMP nsWindow::Show(PRBool 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
if (mIsTooSmall)
return NS_OK;
return;
// show
if (bState)
mInternalShown = aVisible;
if (aVisible)
{
// show mSuperWin
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.y = aY;
ResetInternalVisibility();
if (mIsToplevel && mShell)
{
#ifdef DEBUG
@ -2736,6 +2758,17 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
mBounds.width = aWidth;
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
// 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->shell_window);
}
mInternalShown = PR_FALSE;
}
else
{
@ -2823,8 +2857,9 @@ NS_IMETHODIMP nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
//g_print("not sending resize event\n");
}
if (nNeedToShow)
if (nNeedToShow) {
Show(PR_TRUE);
}
if (aRepaint)
Invalidate(PR_FALSE);

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

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