diff options
author | Timothy Pearson <[email protected]> | 2013-05-07 00:12:51 -0500 |
---|---|---|
committer | Timothy Pearson <[email protected]> | 2013-05-07 00:12:51 -0500 |
commit | 3421d01bb00aaf52883a4d21eade96e9c663e05d (patch) | |
tree | f294c52c8d1d12774629a2d410ec157504af3f57 /tdm/kfrontend | |
parent | 9804217b51b058fed43a060a746f543da044b2a5 (diff) | |
download | tdebase-3421d01bb00aaf52883a4d21eade96e9c663e05d.tar.gz tdebase-3421d01bb00aaf52883a4d21eade96e9c663e05d.zip |
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
Diffstat (limited to 'tdm/kfrontend')
-rw-r--r-- | tdm/kfrontend/kgapp.cpp | 15 | ||||
-rw-r--r-- | tdm/kfrontend/kgreeter.cpp | 6 | ||||
-rw-r--r-- | tdm/kfrontend/themer/tdmitem.cpp | 13 | ||||
-rw-r--r-- | tdm/kfrontend/themer/tdmpixmap.cpp | 108 | ||||
-rw-r--r-- | tdm/kfrontend/themer/tdmrect.cpp | 33 | ||||
-rw-r--r-- | tdm/kfrontend/themer/tdmthemer.cpp | 131 | ||||
-rw-r--r-- | tdm/kfrontend/themes/o2_enterprise/enterprise.xml | 2 |
7 files changed, 188 insertions, 120 deletions
diff --git a/tdm/kfrontend/kgapp.cpp b/tdm/kfrontend/kgapp.cpp index 8a7baeaf3..1a4bdb9ef 100644 --- a/tdm/kfrontend/kgapp.cpp +++ b/tdm/kfrontend/kgapp.cpp @@ -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()); diff --git a/tdm/kfrontend/kgreeter.cpp b/tdm/kfrontend/kgreeter.cpp index 0d89b065c..5ff8d5516 100644 --- a/tdm/kfrontend/kgreeter.cpp +++ b/tdm/kfrontend/kgreeter.cpp @@ -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); } diff --git a/tdm/kfrontend/themer/tdmitem.cpp b/tdm/kfrontend/themer/tdmitem.cpp index 91ab5efda..006a77d49 100644 --- a/tdm/kfrontend/themer/tdmitem.cpp +++ b/tdm/kfrontend/themer/tdmitem.cpp @@ -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 ); + } } diff --git a/tdm/kfrontend/themer/tdmpixmap.cpp b/tdm/kfrontend/themer/tdmpixmap.cpp index 35e3dcc40..2e15218fb 100644 --- a/tdm/kfrontend/themer/tdmpixmap.cpp +++ b/tdm/kfrontend/themer/tdmpixmap.cpp @@ -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(); } diff --git a/tdm/kfrontend/themer/tdmrect.cpp b/tdm/kfrontend/themer/tdmrect.cpp index 9056a513c..a92b0f679 100644 --- a/tdm/kfrontend/themer/tdmrect.cpp +++ b/tdm/kfrontend/themer/tdmrect.cpp @@ -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(); } diff --git a/tdm/kfrontend/themer/tdmthemer.cpp b/tdm/kfrontend/themer/tdmthemer.cpp index d485ab1ee..70a20a5e9 100644 --- a/tdm/kfrontend/themer/tdmthemer.cpp +++ b/tdm/kfrontend/themer/tdmthemer.cpp @@ -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" diff --git a/tdm/kfrontend/themes/o2_enterprise/enterprise.xml b/tdm/kfrontend/themes/o2_enterprise/enterprise.xml index cf8aecd32..39f159b00 100644 --- a/tdm/kfrontend/themes/o2_enterprise/enterprise.xml +++ b/tdm/kfrontend/themes/o2_enterprise/enterprise.xml @@ -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" /> |