Live resize is possible for BeOS widget implementation.
patch by sergei_d@fi.tartu.ee (Sergei Dolgov), r=biesi, no sr needed (beos
only)
This commit is contained in:
cbiesinger%web.de 2004-01-18 20:49:45 +00:00
Родитель b4359d61ff
Коммит b9fb06417a
2 изменённых файлов: 136 добавлений и 177 удалений

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

@ -431,7 +431,7 @@ nsresult nsWindow::StandardWindowCreate(nsIWidget *aParent,
window_feel feel = B_NORMAL_WINDOW_FEEL; window_feel feel = B_NORMAL_WINDOW_FEEL;
// Set all windows to use outline resize, since currently, the redraw of the window during resize // Set all windows to use outline resize, since currently, the redraw of the window during resize
// is very "choppy" // is very "choppy"
uint32 flags = B_ASYNCHRONOUS_CONTROLS | B_OUTLINE_RESIZE; uint32 flags = B_ASYNCHRONOUS_CONTROLS | B_FRAME_EVENTS;
#ifdef MOZ_DEBUG_WINDOW_CREATE #ifdef MOZ_DEBUG_WINDOW_CREATE
printf("%s\n", (mWindowType == eWindowType_popup) ? "popup" : printf("%s\n", (mWindowType == eWindowType_popup) ? "popup" :
@ -459,8 +459,8 @@ nsresult nsWindow::StandardWindowCreate(nsIWidget *aParent,
case eWindowType_toplevel: case eWindowType_toplevel:
case eWindowType_invisible: case eWindowType_invisible:
{ {
// This was never documented, so I'm not sure why we do it, yet // This was never documented, so I'm not sure why we did it
winrect.OffsetBy( 10, 30 ); //winrect.OffsetBy( 10, 30 );
#ifdef MOZ_DEBUG_WINDOW_CREATE #ifdef MOZ_DEBUG_WINDOW_CREATE
printf("\tBorder Style : "); printf("\tBorder Style : ");
@ -598,7 +598,7 @@ NS_METHOD nsWindow::Create(nsNativeWidget aParent,
BView *nsWindow::CreateBeOSView() BView *nsWindow::CreateBeOSView()
{ {
return new nsViewBeOS(this, BRect(0, 0, 0, 0), "", 0, B_WILL_DRAW); return new nsViewBeOS(this, BRect(0,0,0,0), "", 0, B_WILL_DRAW | B_FRAME_EVENTS);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -1004,18 +1004,24 @@ nsresult nsWindow::Move(PRInt32 aX, PRInt32 aY)
havewindow = true; havewindow = true;
if(mView->Parent() || ! havewindow) if(mView->Parent() || ! havewindow)
{
mView->MoveTo(aX, aY); mView->MoveTo(aX, aY);
}
else else
{
mView->Window()->MoveTo(aX, aY); mView->Window()->MoveTo(aX, aY);
}
if(mustunlock) if(mustunlock)
mView->UnlockLooper(); mView->UnlockLooper();
} }
else
OnMove(aX,aY);
return NS_OK; return NS_OK;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// //
// Resize this component // Resize this component
@ -1044,20 +1050,18 @@ NS_METHOD nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
if(mView->Parent() || ! havewindow) if(mView->Parent() || ! havewindow)
mView->ResizeTo(aWidth-1, GetHeight(aHeight)-1); mView->ResizeTo(aWidth-1, GetHeight(aHeight)-1);
else else
((nsWindowBeOS *)mView->Window())->ResizeToWithoutEvent(aWidth-1, GetHeight(aHeight)-1); ((nsWindowBeOS *)mView->Window())->ResizeTo(aWidth-1, GetHeight(aHeight)-1);
if (aRepaint) //This caused senseless blinking on page reload. Do we need it?
mView->Invalidate(); //if (aRepaint && mustunlock)
// mView->Invalidate();
if(mustunlock) if(mustunlock)
mView->UnlockLooper(); mView->UnlockLooper();
//inform the xp layer of the change in size
OnResize(mBounds);
} }
else else
{ {
//inform the xp layer of the change in size
OnResize(mBounds); OnResize(mBounds);
} }
@ -1076,7 +1080,6 @@ NS_METHOD nsWindow::Resize(PRInt32 aX,
PRBool aRepaint) PRBool aRepaint)
{ {
Move(aX,aY); Move(aX,aY);
// Resize will unlock the looper when the above leaves it locked, so it must go last
Resize(aWidth,aHeight,aRepaint); Resize(aWidth,aHeight,aRepaint);
return NS_OK; return NS_OK;
} }
@ -1745,19 +1748,25 @@ bool nsWindow::CallMethod(MethodInfo *info)
if (!mEnabled) if (!mEnabled)
return false; return false;
DispatchFocus(NS_GOTFOCUS); DispatchFocus(NS_GOTFOCUS);
if(mJustGotActivate)
{ //Old hack borrowed from MS Windows code. Will test how good it works without hack.
mJustGotActivate = PR_FALSE; //Same for all further occurencies of mJustGot variables
DispatchFocus(NS_ACTIVATE);
} //if(mJustGotActivate)
//if(mJustGotActivate)
//{
// mJustGotActivate = PR_FALSE;
// DispatchFocus(NS_ACTIVATE);
//}
break; break;
case nsWindow::KILL_FOCUS: case nsWindow::KILL_FOCUS:
NS_ASSERTION(info->nArgs == 1, "Wrong number of arguments to CallMethod"); NS_ASSERTION(info->nArgs == 1, "Wrong number of arguments to CallMethod");
if(mJustGotDeactivate) //This was old hack borrowed from MS Windows code.
{ //if(mJustGotDeactivate)
DispatchFocus(NS_DEACTIVATE); //{
} // DispatchFocus(NS_DEACTIVATE);
//}
DispatchFocus(NS_LOSTFOCUS); DispatchFocus(NS_LOSTFOCUS);
break; break;
@ -1856,20 +1865,13 @@ bool nsWindow::CallMethod(MethodInfo *info)
nsViewBeOS *bv = dynamic_cast<nsViewBeOS *>(mView); nsViewBeOS *bv = dynamic_cast<nsViewBeOS *>(mView);
if(bv && bv->GetPaintRegion(&reg) && reg.Frame().IsValid()) if(bv && bv->GetPaintRegion(&reg) && reg.Frame().IsValid())
{ {
int32 rects = reg.CountRects(); //TODO: provide region for OnPaint(). Not only rect.
for(int32 i = 0; i < rects; ++i) BRect br = reg.Frame();
{ nsRect r(nscoord(br.left), nscoord(br.top),
nsRect r; nscoord(br.IntegerWidth() + 1), nscoord(br.IntegerHeight() + 1));
BRect br = reg.RectAt(i);
r.x = (nscoord)br.left;
r.y = (nscoord)br.top;
r.width = (nscoord)br.IntegerWidth() + 1;
r.height = (nscoord)br.IntegerHeight() + 1;
OnPaint(r); OnPaint(r);
} }
} }
}
break; break;
case nsWindow::ONRESIZE : case nsWindow::ONRESIZE :
@ -1903,8 +1905,10 @@ bool nsWindow::CallMethod(MethodInfo *info)
break; break;
case nsWindow::ONACTIVATE: case nsWindow::ONACTIVATE:
NS_ASSERTION(info->nArgs == 1, "Wrong number of arguments to CallMethod"); NS_ASSERTION(info->nArgs == 2, "Wrong number of arguments to CallMethod");
if (!mEnabled || eWindowType_popup == mWindowType) if (!mEnabled || eWindowType_popup == mWindowType || 0 == mView->Window())
return false;
if((BWindow *)info->args[1] != mView->Window())
return false; return false;
if (*mEventCallback || eWindowType_child == mWindowType) if (*mEventCallback || eWindowType_child == mWindowType)
{ {
@ -1915,16 +1919,17 @@ bool nsWindow::CallMethod(MethodInfo *info)
eWindowType_toplevel == mWindowType) eWindowType_toplevel == mWindowType)
DealWithPopups(ONACTIVATE,nsPoint(0,0)); DealWithPopups(ONACTIVATE,nsPoint(0,0));
DispatchFocus(NS_DEACTIVATE); DispatchFocus(NS_DEACTIVATE);
mJustGotDeactivate = PR_TRUE; //mJustGotDeactivate = PR_TRUE;
} }
else else
{ {
DispatchFocus(NS_ACTIVATE); DispatchFocus(NS_ACTIVATE);
mJustGotActivate = PR_TRUE; //mJustGotActivate = PR_TRUE;
if (mView && mView->Window()) if (mView && mView->Window())
gLastActiveWindow = mView->Window(); gLastActiveWindow = mView->Window();
if(mWindowType == eWindowType_dialog) //Old hack. It seems no need for this at moment, but who knows.
SetFocus(PR_TRUE); //if(mWindowType == eWindowType_dialog)
// SetFocus(PR_TRUE);
} }
} }
break; break;
@ -2589,19 +2594,14 @@ nsIWidget *nsIWidgetStore::GetMozillaWidget(void)
nsWindowBeOS::nsWindowBeOS( nsIWidget *aWidgetWindow, BRect aFrame, const char *aName, window_look aLook, nsWindowBeOS::nsWindowBeOS( nsIWidget *aWidgetWindow, BRect aFrame, const char *aName, window_look aLook,
window_feel aFeel, int32 aFlags, int32 aWorkspace ) window_feel aFeel, int32 aFlags, int32 aWorkspace )
: BWindow( aFrame, aName, aLook, aFeel, aFlags, aWorkspace ), : BWindow( aFrame, aName, aLook, aFeel, aFlags, aWorkspace ),
nsIWidgetStore( aWidgetWindow ), nsIWidgetStore( aWidgetWindow )
resizeRunner(NULL)
{ {
//note that the window will be resized (and FrameResized() //placeholder for initialization
//will be called) if aFrame isn't a valid window size
lastWidth=aFrame.Width();
lastHeight=aFrame.Height();
} }
nsWindowBeOS::~nsWindowBeOS() nsWindowBeOS::~nsWindowBeOS()
{ {
//clean up //placeholder for clean up
delete resizeRunner;
} }
bool nsWindowBeOS::QuitRequested( void ) bool nsWindowBeOS::QuitRequested( void )
@ -2621,25 +2621,8 @@ bool nsWindowBeOS::QuitRequested( void )
void nsWindowBeOS::MessageReceived(BMessage *msg) void nsWindowBeOS::MessageReceived(BMessage *msg)
{ {
switch (msg->what) //Placeholder for possible improvements, e.g. DND and quitting
{
case 'RESZ':
{
// this is the message generated by the resizeRunner - it
// has now served its purpose
delete resizeRunner;
resizeRunner=NULL;
//kick off the xp resizing stuff
DoFrameResized();
}
break;
default :
BWindow::MessageReceived(msg); BWindow::MessageReceived(msg);
break;
}
} }
// This function calls KeyDown() for Alt+whatever instead of app_server // This function calls KeyDown() for Alt+whatever instead of app_server
@ -2656,18 +2639,22 @@ void nsWindowBeOS::DispatchMessage(BMessage *msg, BHandler *handler)
BWindow::DispatchMessage(msg, handler); BWindow::DispatchMessage(msg, handler);
} }
//This method serves single purpose here - allows Mozilla to save current window position,
//and restore position on new start.
void nsWindowBeOS::FrameMoved(BPoint origin) void nsWindowBeOS::FrameMoved(BPoint origin)
{ {
//determine if the window position actually changed //determine if the window position actually changed
if (origin.x == lastpoint.x && origin.x == lastpoint.x) { if (origin.x == lastWindowPoint.x && origin.x == lastWindowPoint.x)
{
//it didn't - don't bother //it didn't - don't bother
return; return;
} }
lastpoint.x = origin.x; lastWindowPoint = origin;
lastpoint.y = origin.y;
nsWindow *w = (nsWindow *)GetMozillaWidget(); nsWindow *w = (nsWindow *)GetMozillaWidget();
nsToolkit *t; nsToolkit *t;
if(w && (t = w->GetToolkit()) != 0) { if(w && (t = w->GetToolkit()) != 0)
{
uint32 args[2]; uint32 args[2];
args[0] = (uint32)origin.x; args[0] = (uint32)origin.x;
args[1] = (uint32)origin.y; args[1] = (uint32)origin.y;
@ -2678,94 +2665,18 @@ void nsWindowBeOS::FrameMoved(BPoint origin)
} }
} }
void nsWindowBeOS::FrameResized(float width, float height)
{
//determine if the window size actually changed
if (width==lastWidth && height==lastHeight) {
//it didn't - don't bother
return;
}
//remember new size
lastWidth=width;
lastHeight=height;
// TODO: This should be removed/commented out, since we are using an outline view
// while the user resizes the window, a large number of
// B_WINDOW_RESIZED events are generated. because
// the layout/drawing code invoked during a resize isn't
// terribly fast, these events can "back up" (new ones are
// delivered before old ones are processed), causing mozilla
// to act sluggish (even on a fast machine, the re-layouts
// and redraws performed in response to the B_WINDOW_RESIZED
// events usually don't finish until long after the user is
// done resizing the window), and possibly even overflow the
// window's event queue. to stop this from happening, we will
// consolidate all B_WINDOW_RESIZED messages generated within
// 1/10 seconds of each other into a single resize event (i.e.,
// the views won't be resized/redrawn until the user finishes
// resizing the window)
const bigtime_t timerLen=100000LL;
if (resizeRunner==NULL) {
//this is the first B_WINDOW_RESIZE event in this interval -
//start the timer
BMessage msg('RESZ');
resizeRunner=new BMessageRunner(BMessenger(this), &msg, timerLen, 1);
} else {
//this is not the first B_WINDOW_RESIZE event in the
//current interval - reset the timer
resizeRunner->SetInterval(timerLen);
}
}
void nsWindowBeOS::ResizeToWithoutEvent(float width, float height)
{
//this method is just a wrapper for BWindow::ResizeTo(), except
//it will attempt to keep the B_FRAME_RESIZED event resulting
//from the ResizeTo() call from being passed to the xp layout
//engine (OnResize() will already have been called for this
//resize by nsWindow::Resize() above)
lastWidth=width;
lastHeight=height;
ResizeTo(width, height);
}
void nsWindowBeOS::DoFrameResized()
{
//let the layout engine know the window has changed size,
//so it can resize the window's views
nsWindow *w = (nsWindow *)GetMozillaWidget();
nsToolkit *t;
if(w && (t = w->GetToolkit()) != 0)
{
//the window's new size needs to be passed to OnResize() -
//note that the values passed to FrameResized() are the
//dimensions as reported by Bounds().Width() and
//Bounds().Height(), which are one pixel smaller than the
//window's true size
uint32 args[2];
args[0]=(uint32)lastWidth+1;
args[1]=(uint32)lastHeight+1;
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::ONRESIZE, 2, args)))
t->CallMethodAsync(info);
NS_RELEASE(t);
}
}
void nsWindowBeOS::WindowActivated(bool active) void nsWindowBeOS::WindowActivated(bool active)
{ {
// Calls method ONACTIVATE to handle mJustGotActivated | mJustGotDeactivated // Calls method ONACTIVATE to dispatch focus ACTIVATE messages
nsWindow *w = (nsWindow *)GetMozillaWidget(); nsWindow *w = (nsWindow *)GetMozillaWidget();
nsToolkit *t; nsToolkit *t;
if(w && (t = w->GetToolkit()) != 0) if(w && (t = w->GetToolkit()) != 0)
{ {
uint32 args[1]; uint32 args[2];
args[0] = (uint32)active; args[0] = (uint32)active;
args[1] = (uint32)this;
MethodInfo *info = nsnull; MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::ONACTIVATE, 1, args))) if(nsnull != (info = new MethodInfo(w, w, nsWindow::ONACTIVATE, 2, args)))
t->CallMethodAsync(info); t->CallMethodAsync(info);
NS_RELEASE(t); NS_RELEASE(t);
} }
@ -2800,6 +2711,8 @@ nsViewBeOS::nsViewBeOS(nsIWidget *aWidgetWindow, BRect aFrame, const char *aName
void nsViewBeOS::AttachedToWindow() void nsViewBeOS::AttachedToWindow()
{ {
lastViewWidth = Bounds().Width();
lastViewHeight = Bounds().Height();
nsWindow *w = (nsWindow *)GetMozillaWidget(); nsWindow *w = (nsWindow *)GetMozillaWidget();
SetHighColor(255, 255, 255); SetHighColor(255, 255, 255);
FillRect(Bounds()); FillRect(Bounds());
@ -2817,11 +2730,13 @@ void nsViewBeOS::DrawAfterChildren(BRect updateRect)
{ {
//Stub for B_DRAW_ON_CHILDREN flags //Stub for B_DRAW_ON_CHILDREN flags
//If some problem appears, line below may be uncommented. //If some problem appears, line below may be uncommented.
// DoDraw(updateRect);
//DoDraw(updateRect);
} }
void nsViewBeOS::DoDraw(BRect updateRect) void nsViewBeOS::DoDraw(BRect updateRect)
{ {
//Collecting update rects here in paintregion
paintregion.Include(updateRect); paintregion.Include(updateRect);
nsWindow *w = (nsWindow *)GetMozillaWidget(); nsWindow *w = (nsWindow *)GetMozillaWidget();
nsToolkit *t; nsToolkit *t;
@ -2835,6 +2750,7 @@ void nsViewBeOS::DoDraw(BRect updateRect)
} }
} }
// Method to get update rects for asynchronous drawing.
bool nsViewBeOS::GetPaintRegion(BRegion *r) bool nsViewBeOS::GetPaintRegion(BRegion *r)
{ {
if(paintregion.CountRects() == 0) if(paintregion.CountRects() == 0)
@ -3068,5 +2984,51 @@ void nsViewBeOS::MakeFocus(bool focused)
void nsViewBeOS::FrameResized(float width, float height) void nsViewBeOS::FrameResized(float width, float height)
{ {
// do nothing //determine if the window size actually changed
if (width==lastViewWidth && height==lastViewHeight)
{
//it didn't - don't bother
return;
}
//remember new size
lastViewWidth=width;
lastViewHeight=height;
nsWindow *w = (nsWindow *)GetMozillaWidget();
nsToolkit *t;
if(w && (t = w->GetToolkit()) != 0)
{
//the window's new size needs to be passed to OnResize() -
//note that the values passed to FrameResized() are the
//dimensions as reported by Bounds().Width() and
//Bounds().Height(), which are one pixel smaller than the
//window's true size
uint32 args[2];
args[0]=(uint32)width+1;
args[1]=(uint32)height+1;
MethodInfo *info = 0;
if (nsnull != (info = new MethodInfo(w, w, nsWindow::ONRESIZE, 2, args)))
t->CallMethodAsync(info);
NS_RELEASE(t);
}
}
void nsViewBeOS::FrameMoved(BPoint origin)
{
//determine if the window position actually changed
if (origin.x == lastViewPoint.x && origin.x == lastViewPoint.x)
return;
lastViewPoint.x = origin.x;
lastViewPoint.y = origin.y;
nsWindow *w = (nsWindow *)GetMozillaWidget();
nsToolkit *t;
if(w && (t = w->GetToolkit()) != 0)
{
uint32 args[2];
args[0] = (uint32)origin.x;
args[1] = (uint32)origin.y;
MethodInfo *info = 0;
if (nsnull != (info = new MethodInfo(w, w, nsWindow::ONMOVE, 2, args)))
t->CallMethodAsync(info);
NS_RELEASE(t);
}
} }

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

@ -298,19 +298,11 @@ public:
virtual void MessageReceived(BMessage *msg); virtual void MessageReceived(BMessage *msg);
virtual void DispatchMessage(BMessage *msg, BHandler *handler); virtual void DispatchMessage(BMessage *msg, BHandler *handler);
virtual void WindowActivated(bool active); virtual void WindowActivated(bool active);
virtual void FrameResized(float width, float height);
virtual void FrameMoved(BPoint origin); virtual void FrameMoved(BPoint origin);
virtual void WorkspacesChanged(uint32 oldworkspace, uint32 newworkspace); virtual void WorkspacesChanged(uint32 oldworkspace, uint32 newworkspace);
void ResizeToWithoutEvent(float width, float height);
private: private:
void DoFrameResized(); BPoint lastWindowPoint;
float lastWidth, lastHeight;
BPoint lastpoint;
BMessageRunner *resizeRunner;
}; };
// //
@ -335,14 +327,19 @@ public:
uint32 transit, uint32 transit,
const BMessage *message); const BMessage *message);
virtual void MouseUp(BPoint point); virtual void MouseUp(BPoint point);
bool GetPaintRegion(/*nsRect &r*/BRegion *breg); bool GetPaintRegion(BRegion *breg);
void KeyDown(const char *bytes, int32 numBytes); void KeyDown(const char *bytes, int32 numBytes);
void KeyUp(const char *bytes, int32 numBytes); void KeyUp(const char *bytes, int32 numBytes);
virtual void MakeFocus(bool focused); virtual void MakeFocus(bool focused);
virtual void MessageReceived(BMessage *msg); virtual void MessageReceived(BMessage *msg);
virtual void FrameResized(float width, float height); virtual void FrameResized(float width, float height);
virtual void FrameMoved(BPoint origin);
private: private:
void DoDraw(BRect updateRect); void DoDraw(BRect updateRect);
float lastViewWidth;
float lastViewHeight;
BPoint lastViewPoint;
}; };
// //