Fix TDM hang in certain circumstances when themed greeter is deleted

This resolves Bug 1453
Resolve themed greeter drawing inconsistencies between composited and non-composited mode
pull/2/head
Timothy Pearson 11 years ago
parent 9804217b51
commit 3421d01bb0

@ -218,6 +218,11 @@ kg_main( const char *argv0 )
#else
trinity_desktop_lock_use_sak = false;
#endif
if (trinity_desktop_lock_use_sak) {
if (system(KDE_BINDIR "/tsak checkdeps") != 0) {
trinity_desktop_lock_use_sak = false;
}
}
if (trinity_desktop_lock_use_sak) {
tsak = new TDEProcess;
*tsak << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + "tsak";
@ -273,10 +278,11 @@ kg_main( const char *argv0 )
XSetErrorHandler( (XErrorHandler)0 );
GreeterApp *app;
if ( (argb_visual_available == true) && (!_compositor.isEmpty()) ) {
if ((!_compositor.isEmpty()) && ( argb_visual_available == true )) {
app = new GreeterApp(dpyi, Qt::HANDLE( visual ), Qt::HANDLE( colormap ));
}
else {
argb_visual_available = false;
app = new GreeterApp(dpyi);
}
// End ARGB initialization
@ -359,6 +365,11 @@ kg_main( const char *argv0 )
}
twin = new TDEProcess;
*twin << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + _windowManager.ascii();
if (_windowManager == "twin") {
// Special case
// Do not allow twin to start kompmgr...
*twin << "--disablecompositionmanager";
}
twin->start();
has_twin = true;
}
@ -492,7 +503,7 @@ kg_main( const char *argv0 )
if (userinfo) {
TQString newuid = TQString("%1").arg(userinfo->pw_uid);
// kompmgr allows us to change its uid in this manner:
// 1.) Send SIGUSER1
// 1.) Send SIGUSR1
// 2.) Send the new UID to it on the command line
comp->kill(SIGUSR1);
comp->writeStdin(newuid.ascii(), newuid.length());

@ -154,8 +154,9 @@ public:
return TDEListView::paintEmptyArea(p, rect );
const TQPixmap *pm = TQT_TQPIXMAP_CONST(paletteBackgroundPixmap());
if (!pm || pm->isNull())
if (!pm || pm->isNull()) {
return;
}
kdDebug() << "paintEmpty " << rect << endl;
TQRect devRect = p->xForm( rect );
@ -1355,6 +1356,9 @@ void ControlPipeHandlerObject::run(void) {
return;
}
}
// Thread cancellation point
usleep(1);
}
TQApplication::eventLoop()->exit(-1);
}

@ -286,17 +286,18 @@ KdmItem::setGeometry( const TQRect &newGeometry, bool force )
void
KdmItem::paint( TQPainter *p, const TQRect &rect )
{
if (isHidden())
if (isHidden()) {
return;
}
if (myWidget || (myLayoutItem && myLayoutItem->widget())) {
// TDEListView because it's missing a Q_OBJECT'
// TDEListView because it's missing a Q_OBJECT
// FIXME: This is a nice idea in theory, but in practice it is
// very confusing for the user not to see the empty list box
// delineated from the rest of the greeter.
// Maybe set a darker version of the background instead of an exact copy?
if ( myWidget && myWidget->isA( "TDEListView" ) ) {
if ((_compositor.isEmpty()) || (!argb_visual_available)) {
if (!argb_visual_available) {
// Software blend only (no compositing support)
TQPixmap copy( myWidget->size() );
kdDebug() << myWidget->geometry() << " " << area << " " << myWidget->size() << endl;
@ -371,13 +372,15 @@ KdmItem::paint( TQPainter *p, const TQRect &rect )
p->drawRect( area );
#endif
if (myLayoutItem)
if (myLayoutItem) {
return;
}
// Dispatch paint events to children
TQValueList<KdmItem *>::Iterator it;
for (it = m_children.begin(); it != m_children.end(); ++it)
for (it = m_children.begin(); it != m_children.end(); ++it) {
(*it)->paint( p, rect );
}
}

@ -69,7 +69,7 @@ KdmPixmap::KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name )
pixmap.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat();
if (el.attribute( "file", "" ) == "@@@TDMBACKGROUND@@@") {
if ((_compositor.isEmpty()) || (!argb_visual_available)) {
if (!argb_visual_available) {
// Software blend only (no compositing support)
// Use the preset TDM background...
TDEStandardDirs *m_pDirs = TDEGlobal::dirs();
@ -111,13 +111,16 @@ KdmPixmap::sizeHint()
{
// choose the correct pixmap class
PixmapStruct::PixmapClass * pClass = &pixmap.normal;
if (state == Sactive && pixmap.active.present)
if (state == Sactive && pixmap.active.present) {
pClass = &pixmap.active;
if (state == Sprelight && pixmap.prelight.present)
}
if (state == Sprelight && pixmap.prelight.present) {
pClass = &pixmap.prelight;
}
// use the pixmap size as the size hint
if (!pClass->pixmap.isNull())
if (!pClass->pixmap.isNull()) {
return pClass->pixmap.size();
}
return KdmItem::sizeHint();
}
@ -134,12 +137,14 @@ KdmPixmap::setGeometry( const TQRect &newGeometry, bool force )
TQString
KdmPixmap::fullPath( const TQString &fileName)
{
if (fileName.isEmpty())
if (fileName.isEmpty()) {
return TQString::null;
}
TQString fullName = fileName;
if (fullName.at( 0 ) != '/')
if (fullName.at( 0 ) != '/') {
fullName = baseDir() + "/" + fileName;
}
return fullName;
}
@ -170,20 +175,22 @@ KdmPixmap::renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area )
void
KdmPixmap::loadPixmap( PixmapStruct::PixmapClass *pClass )
{
TQString fullpath = pClass->fullpath;
kdDebug() << timestamp() << " load " << fullpath << endl;
int index = fullpath.findRev('.');
TQString ext = fullpath.right(fullpath.length() - index);
fullpath = fullpath.left(index);
kdDebug() << timestamp() << " ext " << ext << " " << fullpath << endl;
TQString testpath = TQString("-%1x%2").arg(area.width()).arg(area.height()) + ext;
kdDebug() << timestamp() << " testing for " << fullpath + testpath << endl;
if (TDEStandardDirs::exists(fullpath + testpath))
pClass->pixmap.load(fullpath + testpath);
else
pClass->pixmap.load( fullpath + ext );
kdDebug() << timestamp() << " done\n";
TQString fullpath = pClass->fullpath;
kdDebug() << timestamp() << " load " << fullpath << endl;
int index = fullpath.findRev('.');
TQString ext = fullpath.right(fullpath.length() - index);
fullpath = fullpath.left(index);
kdDebug() << timestamp() << " ext " << ext << " " << fullpath << endl;
TQString testpath = TQString("-%1x%2").arg(area.width()).arg(area.height()) + ext;
kdDebug() << timestamp() << " testing for " << fullpath + testpath << endl;
if (TDEStandardDirs::exists(fullpath + testpath)) {
pClass->pixmap.load(fullpath + testpath);
}
else {
pClass->pixmap.load( fullpath + ext );
}
kdDebug() << timestamp() << " done\n";
}
void
@ -191,16 +198,19 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
{
// choose the correct pixmap class
PixmapStruct::PixmapClass *pClass = &pixmap.normal;
if (state == Sactive && pixmap.active.present)
if (state == Sactive && pixmap.active.present) {
pClass = &pixmap.active;
if (state == Sprelight && pixmap.prelight.present)
}
if (state == Sprelight && pixmap.prelight.present) {
pClass = &pixmap.prelight;
}
kdDebug() << "draw " << id << " " << pClass->pixmap.isNull() << endl;
if (pClass->pixmap.isNull()) {
if (pClass->fullpath.isEmpty()) // if neither is set, we're empty
if (pClass->fullpath.isEmpty()) { // if neither is set, we're empty
return;
}
if (!pClass->fullpath.endsWith( ".svg" ) ) {
loadPixmap(pClass);
@ -230,21 +240,20 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
if (pClass->readyPixmap.isNull()) {
bool haveTint = pClass->tint.rgb() != 0xFFFFFF;
bool haveAlpha = pClass->alpha < 1.0;
TQImage scaledImage;
// use the loaded pixmap or a scaled version if needed
// use the loaded pixmap or a scaled version if needed
kdDebug() << timestamp() << " prepare readyPixmap " << pClass->fullpath << " " << area.size() << " " << pClass->pixmap.size() << endl;
if (area.size() != pClass->pixmap.size()) {
if (pClass->fullpath.endsWith( ".svg" )) {
kdDebug() << timestamp() << " renderSVG\n";
renderSvg( pClass, area );
scaledImage = pClass->pixmap.convertToImage();
} else {
}
else {
kdDebug() << timestamp() << " convertFromImage smoothscale\n";
if (pClass->pixmap.isNull()) {
scaledImage = TQImage();
@ -256,20 +265,22 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
}
kdDebug() << timestamp() << " done\n";
}
} else {
if (haveTint || haveAlpha)
{
scaledImage = pClass->pixmap.convertToImage();
// enforce rgba values for the latter
if (!scaledImage.isNull()) scaledImage = scaledImage.convertDepth( 32 );
}
else
pClass->readyPixmap = pClass->pixmap;
}
else {
if (haveTint || haveAlpha) {
scaledImage = pClass->pixmap.convertToImage();
// enforce rgba values for the latter
if (!scaledImage.isNull()) {
scaledImage = scaledImage.convertDepth( 32 );
}
}
else {
pClass->readyPixmap = pClass->pixmap;
}
}
if (haveTint || haveAlpha) {
// blend image(pix) with the given tint
if (!scaledImage.isNull()) scaledImage = scaledImage.convertDepth( 32 );
int w = scaledImage.width();
int h = scaledImage.height();
@ -290,18 +301,13 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
}
}
}
if ((_compositor.isEmpty()) || (!argb_visual_available)) {
// Software blend only (no compositing support)
}
else {
// We have a compositor!
// Apply the alpha in the same manner as above, exept we are now
// using the hardware blending engine for all painting
scaledImage = pClass->readyPixmap;
// Convert pixmap from premultiplied alpha to normal alpha
{
if (scaledImage.isNull()) scaledImage = pClass->readyPixmap;
if (!scaledImage.isNull()) scaledImage = scaledImage.convertDepth( 32 );
int w = scaledImage.width();
int h = scaledImage.height();
for (int y = 0; y < h; ++y) {
QRgb *ls = (QRgb *)scaledImage.scanLine( y );
for (int x = 0; x < w; ++x) {
@ -317,8 +323,8 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r )
}
if (!scaledImage.isNull()) {
kdDebug() << timestamp() << " convertFromImage " << id << " " << area << endl;
pClass->readyPixmap.convertFromImage( scaledImage );
kdDebug() << timestamp() << " convertFromImage " << id << " " << area << endl;
pClass->readyPixmap.convertFromImage( scaledImage );
}
}
kdDebug() << timestamp() << " Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl;
@ -329,11 +335,13 @@ void
KdmPixmap::statusChanged()
{
KdmItem::statusChanged();
if (!pixmap.active.present && !pixmap.prelight.present)
if (!pixmap.active.present && !pixmap.prelight.present) {
return;
}
if ((state == Sprelight && !pixmap.prelight.present) ||
(state == Sactive && !pixmap.active.present))
(state == Sactive && !pixmap.active.present)) {
return;
}
needUpdate();
}

@ -57,8 +57,9 @@ KdmRect::init( const TQDomNode &node, const char * )
rect.hasBorder = false;
// A rect can have no properties (defaults to parent ones)
if (node.isNull())
if (node.isNull()) {
return;
}
// Read RECT ID
TQDomNode n = node;
@ -75,18 +76,22 @@ KdmRect::init( const TQDomNode &node, const char * )
parseColor( el.attribute( "color", TQString::null ), rect.normal.color );
rect.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat();
parseFont( el.attribute( "font", "Sans 14" ), rect.normal.font );
} else if (tagName == "active") {
}
else if (tagName == "active") {
rect.active.present = true;
parseColor( el.attribute( "color", TQString::null ), rect.active.color );
rect.active.alpha = el.attribute( "alpha", "1.0" ).toFloat();
parseFont( el.attribute( "font", "Sans 14" ), rect.active.font );
} else if (tagName == "prelight") {
}
else if (tagName == "prelight") {
rect.prelight.present = true;
parseColor( el.attribute( "color", TQString::null ), rect.prelight.color );
rect.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat();
parseFont( el.attribute( "font", "Sans 14" ), rect.prelight.font );
} else if (tagName == "border")
}
else if (tagName == "border") {
rect.hasBorder = true;
}
}
}
@ -95,18 +100,22 @@ KdmRect::drawContents( TQPainter *p, const TQRect &r )
{
// choose the correct rect class
RectStruct::RectClass *rClass = &rect.normal;
if (state == Sactive && rect.active.present)
if (state == Sactive && rect.active.present) {
rClass = &rect.active;
if (state == Sprelight && rect.prelight.present)
}
if (state == Sprelight && rect.prelight.present) {
rClass = &rect.prelight;
}
if (rClass->alpha <= 0 || !rClass->color.isValid())
if (rClass->alpha <= 0 || !rClass->color.isValid()) {
return;
}
if (rClass->alpha == 1)
if (rClass->alpha == 1) {
p->fillRect( area, TQBrush( rClass->color ) );
}
else {
// if ((_compositor.isEmpty()) || (!argb_visual_available)) {
// if (!argb_visual_available) {
// Software blend only (no compositing support)
TQRect backRect = r;
backRect.moveBy( area.x(), area.y() );
@ -127,11 +136,13 @@ void
KdmRect::statusChanged()
{
KdmItem::statusChanged();
if (!rect.active.present && !rect.prelight.present)
if (!rect.active.present && !rect.prelight.present) {
return;
}
if ((state == Sprelight && !rect.prelight.present) ||
(state == Sactive && !rect.active.present))
(state == Sactive && !rect.active.present)) {
return;
}
needUpdate();
}

@ -161,12 +161,14 @@ KdmThemer::widgetEvent( TQEvent *e )
TQRect paintRect = TQT_TQPAINTEVENT(e)->rect();
kdDebug() << timestamp() << " paint on: " << paintRect << endl;
if ((_compositor.isEmpty()) || (!argb_visual_available)) {
if (!argb_visual_available) {
// Software blend only (no compositing support)
if (!backBuffer)
if (!backBuffer) {
backBuffer = new TQPixmap( widget()->size() );
if (backBuffer->size() != widget()->size())
}
if (backBuffer->size() != widget()->size()) {
backBuffer->resize( widget()->size() );
}
TQPainter p;
p.begin( backBuffer );
@ -177,17 +179,27 @@ KdmThemer::widgetEvent( TQEvent *e )
}
else {
// We have compositing support!
if (!backBuffer) {
backBuffer = new TQPixmap( widget()->size(), 32 );
}
if (backBuffer->size() != widget()->size()) {
backBuffer->resize( widget()->size() );
}
TQRgb blend_color = tqRgba(0, 0, 0, 0); // RGBA
float alpha = tqAlpha(blend_color) / 255.;
int pixel = tqAlpha(blend_color) << 24 |
int(tqRed(blend_color) * alpha) << 16 |
int(tqGreen(blend_color) * alpha) << 8 |
int(tqBlue(blend_color) * alpha);
TQPainter p1;
p1.begin( widget() );
p1.fillRect( paintRect, TQColor(blend_color, pixel) );
rootItem->paint( &p1, paintRect );
p1.end();
TQPainter p;
p.begin( backBuffer );
p.fillRect( paintRect, TQColor(blend_color, pixel) );
rootItem->paint( &p, paintRect );
p.end();
bitBlt( widget(), paintRect.topLeft(), backBuffer, paintRect );
}
}
@ -238,13 +250,15 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node )
TQString tagName = el.tagName();
if (tagName == "item") {
if (!willDisplay( subnode ))
if (!willDisplay( subnode )) {
continue;
}
TQString id = el.attribute("id");
if (id.startsWith("plugin-specific-")) {
id = id.mid(strlen("plugin-specific-"));
if (!_pluginsLogin.contains(id))
continue;
id = id.mid(strlen("plugin-specific-"));
if (!_pluginsLogin.contains(id)) {
continue;
}
}
// It's a new item. Draw it
@ -252,33 +266,40 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node )
KdmItem *newItem = 0;
if (type == "label")
if (type == "label") {
newItem = new KdmLabel( parent, subnode );
else if (type == "pixmap")
}
else if (type == "pixmap") {
newItem = new KdmPixmap( parent, subnode );
else if (type == "rect")
}
else if (type == "rect") {
newItem = new KdmRect( parent, subnode );
}
else if (type == "entry" || type == "list") {
newItem = new KdmRect( parent, subnode );
newItem->setType( type );
}
// newItem = new KdmEntry( parent, subnode );
else if (type == "svg")
else if (type == "svg") {
newItem = new KdmPixmap( parent, subnode );
}
if (newItem) {
generateItems( newItem, subnode );
if (el.attribute( "button", "false" ) == "true")
if (el.attribute( "button", "false" ) == "true") {
newItem->inheritFromButton( newItem );
}
}
} else if (tagName == "box") {
if (!willDisplay( subnode ))
if (!willDisplay( subnode )) {
continue;
}
// It's a new box. Draw it
parent->setBoxLayout( subnode );
generateItems( parent, subnode );
} else if (tagName == "fixed") {
if (!willDisplay( subnode ))
if (!willDisplay( subnode )) {
continue;
}
// It's a new box. Draw it
parent->setFixedLayout( subnode );
generateItems( parent, subnode );
@ -336,8 +357,9 @@ KdmThemer::showStructure( TQObject *obj )
const TQObjectList wlist = obj->childrenListObject();
static int counter = 0;
if (counter == 0)
if (counter == 0) {
kdDebug() << timestamp() << " \n\n<======= Widget tree =================" << endl;
}
if (!wlist.isEmpty()) {
counter++;
TQObjectListIterator it( wlist );
@ -358,47 +380,56 @@ KdmThemer::showStructure( TQObject *obj )
}
counter--;
}
if (counter == 0)
if (counter == 0) {
kdDebug() << timestamp() << " \n\n<======= Widget tree =================\n\n" << endl;
}
}
void
KdmThemer::slotActivated( const TQString &id )
{
TQString toactivate;
if (id == "username-label")
toactivate = "user-entry";
else if (id == "password-label")
toactivate = "pw-entry";
else
return;
KdmItem *item = findNode(toactivate);
if (!item || !item->widget())
return;
item->widget()->setFocus();
TQLineEdit *le = (TQLineEdit*)item->widget()->tqt_cast(TQLINEEDIT_OBJECT_NAME_STRING);
if (le)
le->selectAll();
TQString toactivate;
if (id == "username-label") {
toactivate = "user-entry";
}
else if (id == "password-label") {
toactivate = "pw-entry";
}
else {
return;
}
KdmItem *item = findNode(toactivate);
if (!item || !item->widget()) {
return;
}
item->widget()->setFocus();
TQLineEdit *le = (TQLineEdit*)item->widget()->tqt_cast(TQLINEEDIT_OBJECT_NAME_STRING);
if (le) {
le->selectAll();
}
}
void
KdmThemer::slotPaintRoot()
{
KdmItem *back_item = findNode("background");
if (!back_item)
return;
TQRect screen = TQApplication::desktop()->screenGeometry(0);
TQPixmap pm(screen.size());
TQPainter painter( &pm, true );
back_item->paint( &painter, back_item->rect());
painter.end();
TQT_TQWIDGET(TQApplication::desktop()->screen())->setErasePixmap(pm);
TQT_TQWIDGET(TQApplication::desktop()->screen())->erase();
KdmItem *back_item = findNode("background");
TQRect screen = TQApplication::desktop()->screenGeometry(0);
TQPixmap pm(screen.size());
if (back_item) {
TQPainter painter( &pm, true );
back_item->paint( &painter, back_item->rect());
painter.end();
}
else {
pm.fill(TQt::black);
}
TQT_TQWIDGET(TQApplication::desktop()->screen())->setErasePixmap(pm);
TQT_TQWIDGET(TQApplication::desktop()->screen())->erase();
}
#include "tdmthemer.moc"

@ -6,7 +6,7 @@
<pos width="100%" x="0" y="0" height="100%" />
</item>
<item type="pixmap" >
<normal file="Dialog.png" />
<normal alpha="1.0" file="Dialog.png" />
<pos width="640" x="50%" y="50%" anchor="c" height="400" />
<item type="label" id="clock" >
<normal color="#000000" font="Sans 10" />

@ -44,6 +44,7 @@ Options* options;
Atoms* atoms;
int screen_number = -1;
bool disable_twin_composition_manager = false;
static bool initting = FALSE;
@ -95,8 +96,13 @@ Application::Application( )
config()->reparseConfiguration();
}
if (screen_number == -1)
if (screen_number == -1) {
screen_number = DefaultScreen(tqt_xdisplay());
}
if (args->isSet( "disablecompositionmanager" )) {
disable_twin_composition_manager = true;
}
if( !owner.claim( args->isSet( "replace" ), true ))
{
@ -234,6 +240,7 @@ static TDECmdLineOptions args[] =
{
{ "lock", I18N_NOOP("Disable configuration options"), 0 },
{ "replace", I18N_NOOP("Replace already-running ICCCM2.0-compliant window manager"), 0 },
{ "disablecompositionmanager", I18N_NOOP("Do not start composition manager"), 0 },
TDECmdLineLastOption
};

@ -59,9 +59,14 @@ TDEProcess* kompmgr = 0;
TDESelectionOwner* kompmgr_selection;
bool allowKompmgrRestart = TRUE;
extern bool disable_twin_composition_manager;
bool supportsCompMgr()
{
if (disable_twin_composition_manager) {
return false;
}
int i;
bool damageExt = XQueryExtension(tqt_xdisplay(), "DAMAGE", &i, &i, &i);
@ -213,8 +218,9 @@ Workspace::Workspace( bool restore )
connect( kapp->desktop(), TQT_SIGNAL( resized( int )), TQT_SLOT( desktopResized()));
#endif
if (!supportsCompMgr())
if (!supportsCompMgr()) {
options->useTranslucency = false;
}
// start kompmgr - i wanted to put this into main.cpp, but that would prevent dcop support, as long as Application was no dcop_object
if (options->useTranslucency)

Loading…
Cancel
Save