overall more correct, most importantly corrected a bug in content scrolling that caused view redraws to ignore the window content clipping
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15627 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
3c0e5f8e8b
commit
bee1ec1ee0
@ -49,17 +49,6 @@
|
|||||||
# define STRACE_CLICK(x) ;
|
# define STRACE_CLICK(x) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// if the background clearing is delayed until
|
|
||||||
// the client draws the view, we have less flickering
|
|
||||||
// when contents have to be redrawn because of resizing
|
|
||||||
// a window or because the client invalidates parts.
|
|
||||||
// when redrawing something that has been exposed from underneath
|
|
||||||
// other windows, the other window will be seen longer at
|
|
||||||
// its previous position though if the exposed parts are not
|
|
||||||
// cleared right away. maybe there ought to be a flag in
|
|
||||||
// the update session, which tells us the cause of the update
|
|
||||||
#define DELAYED_BACKGROUND_CLEARING 0
|
|
||||||
|
|
||||||
// IMPORTANT: nested LockSingleWindow()s are not supported (by MultiLocker)
|
// IMPORTANT: nested LockSingleWindow()s are not supported (by MultiLocker)
|
||||||
|
|
||||||
using std::nothrow;
|
using std::nothrow;
|
||||||
@ -435,6 +424,7 @@ WindowLayer::ScrollViewBy(ViewLayer* view, int32 dx, int32 dy)
|
|||||||
//fDrawingEngine->FillRegion(dirty, RGBColor(255, 0, 255, 255));
|
//fDrawingEngine->FillRegion(dirty, RGBColor(255, 0, 255, 255));
|
||||||
//snooze(2000);
|
//snooze(2000);
|
||||||
|
|
||||||
|
dirty.IntersectWith(&VisibleContentRegion());
|
||||||
_TriggerContentRedraw(dirty);
|
_TriggerContentRedraw(dirty);
|
||||||
|
|
||||||
fDesktop->UnlockSingleWindow();
|
fDesktop->UnlockSingleWindow();
|
||||||
@ -707,12 +697,12 @@ WindowLayer::InvalidateView(ViewLayer* layer, BRegion& layerRegion)
|
|||||||
_UpdateContentRegion();
|
_UpdateContentRegion();
|
||||||
|
|
||||||
layer->ConvertToScreen(&layerRegion);
|
layer->ConvertToScreen(&layerRegion);
|
||||||
layerRegion.IntersectWith(&fVisibleRegion);
|
layerRegion.IntersectWith(&VisibleContentRegion());
|
||||||
if (layerRegion.CountRects() > 0) {
|
if (layerRegion.CountRects() > 0) {
|
||||||
layerRegion.IntersectWith(&layer->ScreenClipping(&fContentRegion));
|
layerRegion.IntersectWith(&layer->ScreenClipping(&fContentRegion));
|
||||||
|
|
||||||
//fDrawingEngine->FillRegion(layerRegion, RGBColor(255, 255, 0, 255));
|
//fDrawingEngine->FillRegion(layerRegion, RGBColor(0, 255, 0, 255));
|
||||||
//snooze(2000);
|
//snooze(10000);
|
||||||
|
|
||||||
_TriggerContentRedraw(layerRegion);
|
_TriggerContentRedraw(layerRegion);
|
||||||
}
|
}
|
||||||
@ -935,24 +925,35 @@ WindowLayer::MouseMoved(BMessage *msg, BPoint where, int32* _viewToken)
|
|||||||
fDrawingEngine->Unlock();
|
fDrawingEngine->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fIsDragging && !(Flags() & B_NOT_MOVABLE)) {
|
BPoint delta = where - fLastMousePosition;
|
||||||
BPoint delta = where - fLastMousePosition;
|
// moving
|
||||||
fDesktop->MoveWindowBy(this, delta.x, delta.y);
|
if (fIsDragging) {
|
||||||
|
if (!(Flags() & B_NOT_MOVABLE))
|
||||||
|
fDesktop->MoveWindowBy(this, delta.x, delta.y);
|
||||||
|
else
|
||||||
|
delta = BPoint(0, 0);
|
||||||
}
|
}
|
||||||
if (fIsResizing && !(Flags() & B_NOT_RESIZABLE)) {
|
// resizing
|
||||||
BPoint delta = where - fLastMousePosition;
|
if (fIsResizing) {
|
||||||
if (Flags() & B_NOT_V_RESIZABLE)
|
if (!(Flags() & B_NOT_RESIZABLE)) {
|
||||||
delta.y = 0;
|
if (Flags() & B_NOT_V_RESIZABLE)
|
||||||
if (Flags() & B_NOT_H_RESIZABLE)
|
delta.y = 0;
|
||||||
delta.x = 0;
|
if (Flags() & B_NOT_H_RESIZABLE)
|
||||||
|
delta.x = 0;
|
||||||
fDesktop->ResizeWindowBy(this, delta.x, delta.y);
|
|
||||||
|
fDesktop->ResizeWindowBy(this, delta.x, delta.y);
|
||||||
|
} else
|
||||||
|
delta = BPoint(0, 0);
|
||||||
}
|
}
|
||||||
|
// sliding tab
|
||||||
if (fIsSlidingTab) {
|
if (fIsSlidingTab) {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
|
|
||||||
fLastMousePosition = where;
|
// NOTE: fLastMousePosition is currently only
|
||||||
|
// used for window moving/resizing/sliding the tab
|
||||||
|
// ther
|
||||||
|
fLastMousePosition += delta;
|
||||||
|
|
||||||
// change focus in FFM mode
|
// change focus in FFM mode
|
||||||
DesktopSettings desktopSettings(fDesktop);
|
DesktopSettings desktopSettings(fDesktop);
|
||||||
@ -1546,23 +1547,24 @@ void
|
|||||||
WindowLayer::_TriggerContentRedraw(BRegion& dirtyContentRegion)
|
WindowLayer::_TriggerContentRedraw(BRegion& dirtyContentRegion)
|
||||||
{
|
{
|
||||||
if (dirtyContentRegion.CountRects() > 0) {
|
if (dirtyContentRegion.CountRects() > 0) {
|
||||||
// send UPDATE message to the client
|
// put this into the pending dirty region
|
||||||
|
// to eventually trigger a client redraw
|
||||||
_TransferToUpdateSession(&dirtyContentRegion);
|
_TransferToUpdateSession(&dirtyContentRegion);
|
||||||
|
|
||||||
|
#if DELAYED_BACKGROUND_CLEARING
|
||||||
|
if (!fTopLayer->IsBackgroundDirty())
|
||||||
|
fTopLayer->MarkBackgroundDirty();
|
||||||
|
#else
|
||||||
if (!fContentRegionValid)
|
if (!fContentRegionValid)
|
||||||
_UpdateContentRegion();
|
_UpdateContentRegion();
|
||||||
|
|
||||||
if (fDrawingEngine->Lock()) {
|
if (fDrawingEngine->Lock()) {
|
||||||
fDrawingEngine->ConstrainClippingRegion(&dirtyContentRegion);
|
fDrawingEngine->ConstrainClippingRegion(&dirtyContentRegion);
|
||||||
#if DELAYED_BACKGROUND_CLEARING
|
|
||||||
fTopLayer->Draw(fDrawingEngine, &dirtyContentRegion,
|
|
||||||
&fContentRegion, false);
|
|
||||||
#else
|
|
||||||
fTopLayer->Draw(fDrawingEngine, &dirtyContentRegion,
|
fTopLayer->Draw(fDrawingEngine, &dirtyContentRegion,
|
||||||
&fContentRegion, true);
|
&fContentRegion, true);
|
||||||
#endif
|
|
||||||
fDrawingEngine->Unlock();
|
fDrawingEngine->Unlock();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1606,6 +1608,9 @@ WindowLayer::_TransferToUpdateSession(BRegion* contentDirtyRegion)
|
|||||||
if (contentDirtyRegion->CountRects() <= 0)
|
if (contentDirtyRegion->CountRects() <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//fDrawingEngine->FillRegion(*contentDirtyRegion, RGBColor(255, 255, 0, 255));
|
||||||
|
//snooze(10000);
|
||||||
|
|
||||||
// add to pending
|
// add to pending
|
||||||
fPendingUpdateSession.SetUsed(true);
|
fPendingUpdateSession.SetUsed(true);
|
||||||
fPendingUpdateSession.Include(contentDirtyRegion);
|
fPendingUpdateSession.Include(contentDirtyRegion);
|
||||||
@ -1616,24 +1621,19 @@ WindowLayer::_TransferToUpdateSession(BRegion* contentDirtyRegion)
|
|||||||
// this could be done smarter (clip layers from pending
|
// this could be done smarter (clip layers from pending
|
||||||
// that have not yet been redrawn in the current update
|
// that have not yet been redrawn in the current update
|
||||||
// session)
|
// session)
|
||||||
|
#if !DELAYED_BACKGROUND_CLEARING
|
||||||
if (fCurrentUpdateSession.IsUsed()) {
|
if (fCurrentUpdateSession.IsUsed()) {
|
||||||
fCurrentUpdateSession.Exclude(contentDirtyRegion);
|
fCurrentUpdateSession.Exclude(contentDirtyRegion);
|
||||||
fEffectiveDrawingRegionValid = false;
|
fEffectiveDrawingRegionValid = false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!fUpdateRequested) {
|
if (!fUpdateRequested) {
|
||||||
// send this to client
|
// send this to client
|
||||||
_SendUpdateMessage();
|
_SendUpdateMessage();
|
||||||
// as long as we have not received
|
// the pending region is now the current,
|
||||||
// the "begin update" command, the
|
// though the update does not start until
|
||||||
// pending session does not become the
|
// we received BEGIN_UPDATE from the client
|
||||||
// current
|
|
||||||
// TODO: problem: since we sent the update regions frame,
|
|
||||||
// we should not add to the pending session after we
|
|
||||||
// sent the update message!!!
|
|
||||||
} else {
|
|
||||||
if (!fCurrentUpdateSession.IsUsed())
|
|
||||||
fprintf(stderr, "WindowLayer(%s)::_TransferToUpdateSession() - pending region changed before BeginUpdate()!\n", Title());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1675,6 +1675,28 @@ WindowLayer::BeginUpdate()
|
|||||||
// session enforced
|
// session enforced
|
||||||
fInUpdate = true;
|
fInUpdate = true;
|
||||||
fEffectiveDrawingRegionValid = false;
|
fEffectiveDrawingRegionValid = false;
|
||||||
|
|
||||||
|
#if DELAYED_BACKGROUND_CLEARING
|
||||||
|
// TODO: each view could be drawn individually
|
||||||
|
// right before carrying out the first drawing
|
||||||
|
// command from the client during an update
|
||||||
|
// (ViewLayer::IsBackgroundDirty() can be used
|
||||||
|
// for this)
|
||||||
|
if (fDrawingEngine->Lock()) {
|
||||||
|
if (!fContentRegionValid)
|
||||||
|
_UpdateContentRegion();
|
||||||
|
|
||||||
|
BRegion dirty(fCurrentUpdateSession.DirtyRegion());
|
||||||
|
dirty.IntersectWith(&VisibleContentRegion());
|
||||||
|
|
||||||
|
fTopLayer->Draw(fDrawingEngine, &dirty,
|
||||||
|
&fContentRegion, true);
|
||||||
|
|
||||||
|
fDrawingEngine->Unlock();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "WindowLayer::BeginUpdate() - no update requested!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fDesktop->UnlockSingleWindow();
|
fDesktop->UnlockSingleWindow();
|
||||||
|
@ -32,6 +32,18 @@ class WindowLayer;
|
|||||||
#define AS_REDRAW 'rdrw'
|
#define AS_REDRAW 'rdrw'
|
||||||
|
|
||||||
|
|
||||||
|
// if the background clearing is delayed until
|
||||||
|
// the client draws the view, we have less flickering
|
||||||
|
// when contents have to be redrawn because of resizing
|
||||||
|
// a window or because the client invalidates parts.
|
||||||
|
// when redrawing something that has been exposed from underneath
|
||||||
|
// other windows, the other window will be seen longer at
|
||||||
|
// its previous position though if the exposed parts are not
|
||||||
|
// cleared right away. maybe there ought to be a flag in
|
||||||
|
// the update session, which tells us the cause of the update
|
||||||
|
#define DELAYED_BACKGROUND_CLEARING 0
|
||||||
|
|
||||||
|
|
||||||
class WindowLayer {
|
class WindowLayer {
|
||||||
public:
|
public:
|
||||||
WindowLayer(const BRect& frame,
|
WindowLayer(const BRect& frame,
|
||||||
@ -105,6 +117,8 @@ class WindowLayer {
|
|||||||
|
|
||||||
void BeginUpdate();
|
void BeginUpdate();
|
||||||
void EndUpdate();
|
void EndUpdate();
|
||||||
|
bool InUpdate() const
|
||||||
|
{ return fInUpdate; }
|
||||||
|
|
||||||
bool NeedsUpdate() const
|
bool NeedsUpdate() const
|
||||||
{ return fUpdateRequested; }
|
{ return fUpdateRequested; }
|
||||||
|
Loading…
Reference in New Issue
Block a user