Bug 227733

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
parent 092dd292b9
commit ad348cd49b
2 changed files with 136 additions and 177 deletions

View File

@ -431,7 +431,7 @@ nsresult nsWindow::StandardWindowCreate(nsIWidget *aParent,
window_feel feel = B_NORMAL_WINDOW_FEEL;
// Set all windows to use outline resize, since currently, the redraw of the window during resize
// is very "choppy"
uint32 flags = B_ASYNCHRONOUS_CONTROLS | B_OUTLINE_RESIZE;
uint32 flags = B_ASYNCHRONOUS_CONTROLS | B_FRAME_EVENTS;
#ifdef MOZ_DEBUG_WINDOW_CREATE
printf("%s\n", (mWindowType == eWindowType_popup) ? "popup" :
@ -459,8 +459,8 @@ nsresult nsWindow::StandardWindowCreate(nsIWidget *aParent,
case eWindowType_toplevel:
case eWindowType_invisible:
{
// This was never documented, so I'm not sure why we do it, yet
winrect.OffsetBy( 10, 30 );
// This was never documented, so I'm not sure why we did it
//winrect.OffsetBy( 10, 30 );
#ifdef MOZ_DEBUG_WINDOW_CREATE
printf("\tBorder Style : ");
@ -598,7 +598,7 @@ NS_METHOD nsWindow::Create(nsNativeWidget aParent,
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;
if(mView->Parent() || ! havewindow)
{
mView->MoveTo(aX, aY);
}
else
mView->Window()->MoveTo(aX, aY);
{
mView->Window()->MoveTo(aX, aY);
}
if(mustunlock)
mView->UnlockLooper();
}
else
OnMove(aX,aY);
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Resize this component
@ -1044,20 +1050,18 @@ NS_METHOD nsWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
if(mView->Parent() || ! havewindow)
mView->ResizeTo(aWidth-1, GetHeight(aHeight)-1);
else
((nsWindowBeOS *)mView->Window())->ResizeToWithoutEvent(aWidth-1, GetHeight(aHeight)-1);
((nsWindowBeOS *)mView->Window())->ResizeTo(aWidth-1, GetHeight(aHeight)-1);
if (aRepaint)
mView->Invalidate();
//This caused senseless blinking on page reload. Do we need it?
//if (aRepaint && mustunlock)
// mView->Invalidate();
if(mustunlock)
mView->UnlockLooper();
//inform the xp layer of the change in size
OnResize(mBounds);
}
else
{
//inform the xp layer of the change in size
OnResize(mBounds);
}
@ -1076,7 +1080,6 @@ NS_METHOD nsWindow::Resize(PRInt32 aX,
PRBool aRepaint)
{
Move(aX,aY);
// Resize will unlock the looper when the above leaves it locked, so it must go last
Resize(aWidth,aHeight,aRepaint);
return NS_OK;
}
@ -1745,19 +1748,25 @@ bool nsWindow::CallMethod(MethodInfo *info)
if (!mEnabled)
return false;
DispatchFocus(NS_GOTFOCUS);
if(mJustGotActivate)
{
mJustGotActivate = PR_FALSE;
DispatchFocus(NS_ACTIVATE);
}
//Old hack borrowed from MS Windows code. Will test how good it works without hack.
//Same for all further occurencies of mJustGot variables
//if(mJustGotActivate)
//if(mJustGotActivate)
//{
// mJustGotActivate = PR_FALSE;
// DispatchFocus(NS_ACTIVATE);
//}
break;
case nsWindow::KILL_FOCUS:
NS_ASSERTION(info->nArgs == 1, "Wrong number of arguments to CallMethod");
if(mJustGotDeactivate)
{
DispatchFocus(NS_DEACTIVATE);
}
//This was old hack borrowed from MS Windows code.
//if(mJustGotDeactivate)
//{
// DispatchFocus(NS_DEACTIVATE);
//}
DispatchFocus(NS_LOSTFOCUS);
break;
@ -1856,19 +1865,12 @@ bool nsWindow::CallMethod(MethodInfo *info)
nsViewBeOS *bv = dynamic_cast<nsViewBeOS *>(mView);
if(bv && bv->GetPaintRegion(&reg) && reg.Frame().IsValid())
{
int32 rects = reg.CountRects();
for(int32 i = 0; i < rects; ++i)
{
nsRect r;
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);
}
//TODO: provide region for OnPaint(). Not only rect.
BRect br = reg.Frame();
nsRect r(nscoord(br.left), nscoord(br.top),
nscoord(br.IntegerWidth() + 1), nscoord(br.IntegerHeight() + 1));
OnPaint(r);
}
}
break;
@ -1903,8 +1905,10 @@ bool nsWindow::CallMethod(MethodInfo *info)
break;
case nsWindow::ONACTIVATE:
NS_ASSERTION(info->nArgs == 1, "Wrong number of arguments to CallMethod");
if (!mEnabled || eWindowType_popup == mWindowType)
NS_ASSERTION(info->nArgs == 2, "Wrong number of arguments to CallMethod");
if (!mEnabled || eWindowType_popup == mWindowType || 0 == mView->Window())
return false;
if((BWindow *)info->args[1] != mView->Window())
return false;
if (*mEventCallback || eWindowType_child == mWindowType)
{
@ -1915,16 +1919,17 @@ bool nsWindow::CallMethod(MethodInfo *info)
eWindowType_toplevel == mWindowType)
DealWithPopups(ONACTIVATE,nsPoint(0,0));
DispatchFocus(NS_DEACTIVATE);
mJustGotDeactivate = PR_TRUE;
//mJustGotDeactivate = PR_TRUE;
}
else
{
DispatchFocus(NS_ACTIVATE);
mJustGotActivate = PR_TRUE;
//mJustGotActivate = PR_TRUE;
if (mView && mView->Window())
gLastActiveWindow = mView->Window();
if(mWindowType == eWindowType_dialog)
SetFocus(PR_TRUE);
//Old hack. It seems no need for this at moment, but who knows.
//if(mWindowType == eWindowType_dialog)
// SetFocus(PR_TRUE);
}
}
break;
@ -2589,19 +2594,14 @@ nsIWidget *nsIWidgetStore::GetMozillaWidget(void)
nsWindowBeOS::nsWindowBeOS( nsIWidget *aWidgetWindow, BRect aFrame, const char *aName, window_look aLook,
window_feel aFeel, int32 aFlags, int32 aWorkspace )
: BWindow( aFrame, aName, aLook, aFeel, aFlags, aWorkspace ),
nsIWidgetStore( aWidgetWindow ),
resizeRunner(NULL)
nsIWidgetStore( aWidgetWindow )
{
//note that the window will be resized (and FrameResized()
//will be called) if aFrame isn't a valid window size
lastWidth=aFrame.Width();
lastHeight=aFrame.Height();
//placeholder for initialization
}
nsWindowBeOS::~nsWindowBeOS()
{
//clean up
delete resizeRunner;
//placeholder for clean up
}
bool nsWindowBeOS::QuitRequested( void )
@ -2613,7 +2613,7 @@ bool nsWindowBeOS::QuitRequested( void )
{
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::CLOSEWINDOW)))
t->CallMethodAsync(info);
t->CallMethodAsync(info);
NS_RELEASE(t);
}
return false;
@ -2621,25 +2621,8 @@ bool nsWindowBeOS::QuitRequested( void )
void nsWindowBeOS::MessageReceived(BMessage *msg)
{
switch (msg->what)
{
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);
break;
}
//Placeholder for possible improvements, e.g. DND and quitting
BWindow::MessageReceived(msg);
}
// This function calls KeyDown() for Alt+whatever instead of app_server
@ -2656,117 +2639,45 @@ void nsWindowBeOS::DispatchMessage(BMessage *msg, BHandler *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)
{
//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
return;
}
lastpoint.x = origin.x;
lastpoint.y = origin.y;
lastWindowPoint = origin;
nsWindow *w = (nsWindow *)GetMozillaWidget();
nsToolkit *t;
if(w && (t = w->GetToolkit()) != 0) {
if(w && (t = w->GetToolkit()) != 0)
{
uint32 args[2];
args[0] = (uint32)origin.x;
args[1] = (uint32)origin.y;
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::ONMOVE, 2, args)))
t->CallMethodAsync(info);
NS_RELEASE(t);
}
}
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);
t->CallMethodAsync(info);
NS_RELEASE(t);
}
}
void nsWindowBeOS::WindowActivated(bool active)
{
// Calls method ONACTIVATE to handle mJustGotActivated | mJustGotDeactivated
// Calls method ONACTIVATE to dispatch focus ACTIVATE messages
nsWindow *w = (nsWindow *)GetMozillaWidget();
nsToolkit *t;
if(w && (t = w->GetToolkit()) != 0)
{
uint32 args[1];
uint32 args[2];
args[0] = (uint32)active;
args[1] = (uint32)this;
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::ONACTIVATE, 1, args)))
t->CallMethodAsync(info);
if(nsnull != (info = new MethodInfo(w, w, nsWindow::ONACTIVATE, 2, args)))
t->CallMethodAsync(info);
NS_RELEASE(t);
}
}
@ -2784,7 +2695,7 @@ void nsWindowBeOS::WorkspacesChanged(uint32 oldworkspace, uint32 newworkspace)
args[1] = oldworkspace;
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::ONWORKSPACE, 2, args)))
t->CallMethodAsync(info);
t->CallMethodAsync(info);
NS_RELEASE(t);
}
}
@ -2800,6 +2711,8 @@ nsViewBeOS::nsViewBeOS(nsIWidget *aWidgetWindow, BRect aFrame, const char *aName
void nsViewBeOS::AttachedToWindow()
{
lastViewWidth = Bounds().Width();
lastViewHeight = Bounds().Height();
nsWindow *w = (nsWindow *)GetMozillaWidget();
SetHighColor(255, 255, 255);
FillRect(Bounds());
@ -2817,11 +2730,13 @@ void nsViewBeOS::DrawAfterChildren(BRect updateRect)
{
//Stub for B_DRAW_ON_CHILDREN flags
//If some problem appears, line below may be uncommented.
// DoDraw(updateRect);
//DoDraw(updateRect);
}
void nsViewBeOS::DoDraw(BRect updateRect)
{
//Collecting update rects here in paintregion
paintregion.Include(updateRect);
nsWindow *w = (nsWindow *)GetMozillaWidget();
nsToolkit *t;
@ -2835,6 +2750,7 @@ void nsViewBeOS::DoDraw(BRect updateRect)
}
}
// Method to get update rects for asynchronous drawing.
bool nsViewBeOS::GetPaintRegion(BRegion *r)
{
if(paintregion.CountRects() == 0)
@ -2868,7 +2784,7 @@ void nsViewBeOS::MouseDown(BPoint point)
args[4] = modifiers();
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::BTNCLICK, 5, args)))
t->CallMethodAsync(info);
t->CallMethodAsync(info);
}
NS_RELEASE(t);
}
@ -2890,20 +2806,20 @@ void nsViewBeOS::MouseMoved(BPoint point, uint32 transit, const BMessage *msg)
args[0] = NS_MOUSE_ENTER;
MethodInfo *enterInfo = nsnull;
if(nsnull != (enterInfo = new MethodInfo(w, w, nsWindow::ONMOUSE, 4, args)))
t->CallMethodAsync(enterInfo);
t->CallMethodAsync(enterInfo);
}
args[0] = NS_MOUSE_MOVE;
MethodInfo *moveInfo = nsnull;
if(nsnull != (moveInfo = new MethodInfo(w, w, nsWindow::ONMOUSE, 4, args)))
t->CallMethodAsync(moveInfo);
t->CallMethodAsync(moveInfo);
if(transit == B_EXITED_VIEW)
{
args[0] = NS_MOUSE_EXIT;
MethodInfo *exitInfo = nsnull;
if(nsnull != (exitInfo = new MethodInfo(w, w, nsWindow::ONMOUSE, 4, args)))
t->CallMethodAsync(exitInfo);
t->CallMethodAsync(exitInfo);
}
NS_RELEASE(t);
}
@ -2928,7 +2844,7 @@ void nsViewBeOS::MouseUp(BPoint point)
args[4] = modifiers();
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::BTNCLICK, 5, args)))
t->CallMethodAsync(info);
t->CallMethodAsync(info);
}
NS_RELEASE(t);
}
@ -2971,7 +2887,7 @@ void nsViewBeOS::MessageReceived(BMessage *msg)
args[0] = (uint32)-3;
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::ONWHEEL, 1, args)))
t->CallMethodAsync(info);
t->CallMethodAsync(info);
NS_RELEASE(t);
}
}
@ -3011,7 +2927,7 @@ void nsViewBeOS::KeyDown(const char *bytes, int32 numBytes)
args[5] = rawcode;
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::ONKEY, 6, args)))
t->CallMethodAsync(info);
t->CallMethodAsync(info);
NS_RELEASE(t);
}
}
@ -3043,7 +2959,7 @@ void nsViewBeOS::KeyUp(const char *bytes, int32 numBytes)
args[5] = rawcode;
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, nsWindow::ONKEY, 6, args)))
t->CallMethodAsync(info);
t->CallMethodAsync(info);
NS_RELEASE(t);
}
}
@ -3061,12 +2977,58 @@ void nsViewBeOS::MakeFocus(bool focused)
args[0]=(uint32)Window();
MethodInfo *info = nsnull;
if(nsnull != (info = new MethodInfo(w, w, (focused)? nsWindow::GOT_FOCUS : nsWindow::KILL_FOCUS,1,args)))
t->CallMethodAsync(info);
t->CallMethodAsync(info);
NS_RELEASE(t);
}
}
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);
}
}

View File

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