Add a simple test that demonstrates that the Haiku app_server incorrectly

(or at least incompatibly) uses the user set clipping region when determining
whether or not to call Draw() on a view. Under BeOS when a some part of a view
is exposed it will always trigger a Draw(), even if the current clipping region
disallows drawing in the supplied update rect. Under Haiku however the view is
not considered for an update when the current clipping region does not
intersect with the newly exposed area.
Running this test app from the Terminal this behaviour can be seen. When
clicking inside the window a floating window pops up. When clicking again it
goes away and triggers a redraw. When hitting a key, a clipping region is set
that does not overlap with the floating window. After this clipping is set,
the view does not get any Draw() call anymore when the floating window goes
away.
This is the reason for the redraw issues in firefox, as firefox uses the
clipping region to constrain its asynchronous drawing, but does never reset
the clipping to NULL. As firefox just collects the update rects in Draw() and
then draws the contents itself, once the clipping region is set, many of the
Draw() calls don't get called and the interface parts are never redrawn.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25853 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2008-06-07 21:53:08 +00:00
parent f31163e967
commit 680a35bbdb
2 changed files with 118 additions and 0 deletions
@@ -0,0 +1,112 @@
#include <Application.h>
#include <Bitmap.h>
#include <Region.h>
#include <View.h>
#include <Window.h>
#include <stdio.h>
class ClippingView : public BView {
public:
ClippingView(BRect frame);
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint where);
virtual void KeyDown(const char *bytes, int32 numBytes);
private:
BWindow * fFloatingWindow;
};
class ClippingWindow : public BWindow {
public:
ClippingWindow(BRect frame);
private:
ClippingView * fView;
};
class ClippingApp : public BApplication {
public:
ClippingApp();
private:
ClippingWindow * fWindow;
};
ClippingApp::ClippingApp()
: BApplication("application/x.vnd-Haiku.ClippingPlusRedraw")
{
fWindow = new ClippingWindow(BRect(200, 200, 500, 400));
fWindow->Show();
}
ClippingWindow::ClippingWindow(BRect frame)
: BWindow(frame, "Window", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE)
{
fView = new ClippingView(frame.OffsetToSelf(0, 0));
AddChild(fView);
fView->MakeFocus();
}
ClippingView::ClippingView(BRect frame)
: BView(frame, "View", B_FOLLOW_ALL, B_WILL_DRAW),
fFloatingWindow(NULL)
{
}
void
ClippingView::Draw(BRect updateRect)
{
printf("got draw with update rect: %f, %f, %f, %f\n",
updateRect.left, updateRect.top, updateRect.right, updateRect.bottom);
SetHighColor(0, 255, 0);
FillRect(Bounds(), B_SOLID_HIGH);
}
void
ClippingView::MouseDown(BPoint where)
{
if (fFloatingWindow == NULL) {
BPoint leftTop = ConvertToScreen(BPoint(50, 50));
fFloatingWindow = new BWindow(BRect(leftTop, leftTop + BPoint(100, 50)),
"Floating", B_FLOATING_WINDOW, B_AVOID_FOCUS);
fFloatingWindow->Show();
} else {
fFloatingWindow->Lock();
fFloatingWindow->Quit();
fFloatingWindow = NULL;
}
}
void
ClippingView::KeyDown(const char *bytes, int32 numBytes)
{
SetHighColor(0, 0, 255);
FillRect(Bounds(), B_SOLID_HIGH);
BRegion region(BRect(200, 100, 250, 150));
ConstrainClippingRegion(&region);
SetHighColor(255, 0, 0);
FillRect(Bounds(), B_SOLID_HIGH);
}
int
main(int argc, const char *argv[])
{
ClippingApp *app = new ClippingApp();
app->Run();
delete app;
return 0;
}
+6
View File
@@ -129,6 +129,12 @@ SimpleTest WidthBufferTest :
: be
;
SimpleTest ClippingPlusRedraw :
ClippingPlusRedraw.cpp
: be
;
SEARCH on [ FGristFiles
ScrollView.cpp CheckBox.cpp ChannelSlider.cpp ChannelControl.cpp Slider.cpp Control.cpp
] = [ FDirName $(HAIKU_TOP) src kits interface ] ;