KDecoration::unobscuredRegion(), for B2 titlebar unhiding.

svn path=/trunk/kdebase/kwin/; revision=262494
This commit is contained in:
Luboš Luňák 2003-10-27 16:28:53 +00:00
parent 1709cb0e44
commit b884178c99
10 changed files with 84 additions and 23 deletions

View file

@ -126,4 +126,31 @@ void Bridge::helperShowHide( bool show )
c->rawHide();
}
QRegion Bridge::unobscuredRegion( const QRegion& r ) const
{
QRegion reg( r );
const ClientList stacking_order = c->workspace()->stackingOrder();
ClientList::ConstIterator it = stacking_order.find( c );
++it;
for(;
it != stacking_order.end();
++it )
{
/* the clients all have their mask-regions in local coords
so we have to translate them to a shared coord system
we choose ours */
int dx = (*it)->x() - c->x();
int dy = (*it)->y() - c->y();
QRegion creg = (*it)->mask();
creg.translate(dx, dy);
reg -= creg;
if (reg.isEmpty())
{
// early out, we are completely obscured
break;
}
}
return reg;
}
} // namespace

View file

@ -46,6 +46,7 @@ class Bridge : public KDecorationBridge
virtual bool isPreview() const;
virtual QRect geometry() const;
virtual QRect iconGeometry() const;
virtual QRegion unobscuredRegion( const QRegion& r ) const;
virtual QWidget* workspaceWidget() const;
virtual void closeWindow();
virtual void maximize( MaximizeMode mode );

View file

@ -437,6 +437,7 @@ void Client::updateShape()
void Client::setMask( const QRegion& reg, int mode )
{
_mask = reg;
if( reg.isNull())
XShapeCombineMask( qt_xdisplay(), frameId(), ShapeBounding, 0, 0,
None, ShapeSet );
@ -462,6 +463,13 @@ void Client::setMask( const QRegion& reg, int mode )
}
}
QRegion Client::mask() const
{
if( _mask.isEmpty())
return QRegion( 0, 0, width(), height());
return _mask;
}
void Client::hideClient( bool hide )
{
if( hidden == hide )

View file

@ -179,6 +179,7 @@ class Client : public QObject, public KDecorationDefines
void demandAttention( bool set = true );
void setMask( const QRegion& r, int mode = X::Unsorted );
QRegion mask() const;
void updateDecoration( bool check_workspace_pos, bool force = false );
void checkBorderSizes();
@ -463,6 +464,7 @@ class Client : public QObject, public KDecorationDefines
int block_geometry; // >0 - new geometry is remembered, but not actually set
bool shade_geometry_change;
int border_left, border_right, border_top, border_bottom;
QRegion _mask;
friend struct FetchNameInternalPredicate;
void show() { assert( false ); } // SELI remove after Client is no longer QWidget
void hide() { assert( false ); }
@ -793,7 +795,7 @@ inline bool Client::hasUserTimeSupport() const
{
return info->userTime() != -1U;
}
#ifdef NDEBUG
kndbgstream& operator<<( kndbgstream& stream, const Client* );
#else

View file

@ -785,7 +785,6 @@ void B2Client::slotReset()
void B2Client::unobscureTitlebar()
{
#if 0 // TODO JUMPYTITLEBAR
/* we just noticed, that we got obscured by other windows
so we look at all windows above us (stacking_order) merging their
masks, intersecting it with our titlebar area, and see if we can
@ -795,23 +794,7 @@ void B2Client::unobscureTitlebar()
}
in_unobs = 1;
QRegion reg(QRect(0,0,width(), buttonSize + 4));
ClientList::ConstIterator it = workspace()->stackingOrder().find(this);
++it;
while (it != workspace()->stackingOrder().end()) {
/* the clients all have their mask-regions in local coords
so we have to translate them to a shared coord system
we choose ours */
int dx = (*it)->x() - x();
int dy = (*it)->y() - y();
QRegion creg = (*it)->getMask();
creg.translate(dx, dy);
reg -= creg;
if (reg.isEmpty()) {
// early out, we are completely obscured
break;
}
++it;
}
reg = unobscuredRegion( reg );
if (!reg.isEmpty()) {
// there is at least _one_ pixel from our title area, which is not
// obscured, we use the first rect we find
@ -820,7 +803,6 @@ void B2Client::unobscureTitlebar()
titleMoveAbs(reg.boundingRect().x());
}
in_unobs = 0;
#endif
}
static void redraw_pixmaps()
@ -1123,8 +1105,6 @@ B2Titlebar::B2Titlebar(B2Client *parent)
QSizePolicy::Expanding, QSizePolicy::Fixed);
}
// TODO JUMPYTITLEBAR This is not useful until titlebar revealing can be reenabled
bool B2Titlebar::x11Event(XEvent *e)
{
if (!set_x11mask) {

View file

@ -163,6 +163,8 @@ void KDecorationPreview::setPreviewMask( const QRegion& reg, int mode, bool acti
xrects, rects.count(), ShapeSet, mode );
delete[] xrects;
}
if( active )
mask = reg; // keep shape of the active window for unobscuredRegion()
}
QRect KDecorationPreview::windowGeometry( bool active ) const
@ -171,6 +173,24 @@ QRect KDecorationPreview::windowGeometry( bool active ) const
return widget->geometry();
}
QRegion KDecorationPreview::unobscuredRegion( bool active, const QRegion& r ) const
{
if( active ) // this one is not obscured
return r;
else
{
// copied from KWin core's code
QRegion ret = r;
QRegion r2 = mask;
if( r2.isEmpty())
r2 = QRegion( windowGeometry( true ));
r2.translate( windowGeometry( true ).x() - windowGeometry( false ).x(),
windowGeometry( true ).y() - windowGeometry( false ).y());
ret -= r2;
return ret;
}
}
KDecorationPreviewBridge::KDecorationPreviewBridge( KDecorationPreview* p, bool a )
: preview( p ), active( a )
{
@ -302,7 +322,12 @@ QRect KDecorationPreviewBridge::iconGeometry() const
{
return QRect();
}
QRegion KDecorationPreviewBridge::unobscuredRegion( const QRegion& r ) const
{
return preview->unobscuredRegion( active, r );
}
QWidget* KDecorationPreviewBridge::workspaceWidget() const
{
return preview;

View file

@ -47,6 +47,7 @@ class KDecorationPreview
void enablePreview();
void disablePreview();
void setPreviewMask( const QRegion&, int, bool );
QRegion unobscuredRegion( bool, const QRegion& ) const;
QRect windowGeometry( bool ) const;
protected:
virtual void resizeEvent( QResizeEvent* );
@ -56,6 +57,7 @@ class KDecorationPreview
KDecorationPreviewBridge* bridge[NumWindows];
KDecoration* deco[NumWindows];
QLabel* no_preview;
QRegion mask;
};
class KDecorationPreviewBridge
@ -87,6 +89,7 @@ class KDecorationPreviewBridge
virtual bool isPreview() const;
virtual QRect geometry() const;
virtual QRect iconGeometry() const;
virtual QRegion unobscuredRegion( const QRegion& r ) const;
virtual QWidget* workspaceWidget() const;
virtual void closeWindow();
virtual void maximize( MaximizeMode mode );

View file

@ -203,6 +203,11 @@ QRect KDecoration::iconGeometry() const
return bridge_->iconGeometry();
}
QRegion KDecoration::unobscuredRegion( const QRegion& r ) const
{
return bridge_->unobscuredRegion( r );
}
QWidget* KDecoration::workspaceWidget() const
{
return bridge_->workspaceWidget();

View file

@ -416,6 +416,15 @@ class KDecoration
* the geometry may be null.
*/
QRect iconGeometry() const;
/**
* Returns the intersection of the given region with the region left
* unobscured by the windows stacked above the current one. You can use
* this function to, for example, try to keep the titlebar visible if
* there is an hole available. The region returned is in the coordinate
* space of the decoration.
* @param r The region you want to check for holes
*/
QRegion unobscuredRegion( const QRegion& r ) const;
/**
* Returns the main workspace widget. The main purpose of this function is to
* allow painting the minimize animation or the transparent move bound on it.

View file

@ -83,6 +83,7 @@ class KDecorationBridge : public KDecorationDefines
virtual bool isPreview() const = 0;
virtual QRect geometry() const = 0;
virtual QRect iconGeometry() const = 0;
virtual QRegion unobscuredRegion( const QRegion& r ) const = 0;
virtual QWidget* workspaceWidget() const = 0;
virtual void closeWindow() = 0;
virtual void maximize( MaximizeMode mode ) = 0;