KMail2

Dec. 16th, 2011 05:56 pm
madf: (Default)
[personal profile] madf
До нього у мене, власне, дві претензії (якщо не рахувати купу питань щодо юзабіліті):

Сьогодні під час компіляції libreoffice (10 Gb tmpfs, 5 паралельних процесів) мені терміново треба була інформація із вчорашнього листа. Перемкнувшись на 6-й десктоп я побачив що? Правильно, сірий квадрат замість KMail. При цьому Akregator, Okular і навіть Firefox працювали без помітних тормозів. Wtf?
strace показав що KMail нічим не зайнятий, тупо висить на select. gdb показав цікаву картинку.

Почнемо знизу:
#52 0x00007f498ff9fabc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib64/qt4/libQtGui.so.4
#53 0x00007f498ff9ed60 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib64/qt4/libQtGui.so.4
#54 0x00007f4990168ad8 in QWidgetBackingStore::sync() () from /usr/lib64/qt4/libQtGui.so.4
#55 0x00007f4990168daa in QWidgetBackingStore::sync(QWidget*, QRegion const&) () from /usr/lib64/qt4/libQtGui.so.4
#56 0x00007f498ffce8b0 in QETWidget::translatePaintEvent(_XEvent const*) () from /usr/lib64/qt4/libQtGui.so.4
#57 0x00007f498ffcf64c in QApplication::x11ProcessEvent(_XEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#58 0x00007f498fff68a2 in x11EventSourceDispatch(_GSource*, int (*)(void*), void*) () from /usr/lib64/qt4/libQtGui.so.4
#59 0x00007f4987ad311a in g_main_context_dispatch () from /usr/lib64/libglib-2.0.so.0
#60 0x00007f4987ad3928 in g_main_context_iterate.clone.6 () from /usr/lib64/libglib-2.0.so.0
#61 0x00007f4987ad3abf in g_main_context_iteration () from /usr/lib64/libglib-2.0.so.0
#62 0x00007f498fa71f5a in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/qt4/libQtCore.so.4
#63 0x00007f498fff6566 in QGuiEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/qt4/libQtGui.so.4
#64 0x00007f498fa46112 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/qt4/libQtCore.so.4
#65 0x00007f498fa46394 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/qt4/libQtCore.so.4
#66 0x00007f498fa4a87b in QCoreApplication::exec() () from /usr/lib64/qt4/libQtCore.so.4
#67 0x00000000004031f2 in main ()

Нічого цікавого. Прилетів pain event і він почав малювати. Далі йдуть з десяток викликів QWidgetPrivate::paintSiblingsRecursive, я не буду їх наводити. Йдемо вище:
#18 0x00007f499048568a in QTreeView::drawRow(QPainter*, QStyleOptionViewItem const&, QModelIndex const&) const () from /usr/lib64/qt4/libQtGui.so.4
#19 0x00007f49904885a5 in QTreeView::drawTree(QPainter*, QRegion const&) const () from /usr/lib64/qt4/libQtGui.so.4
#20 0x00007f4990488f9f in QTreeView::paintEvent(QPaintEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#21 0x00007f498ffa2135 in QWidget::event(QEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#22 0x00007f49903391de in QFrame::event(QEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#23 0x00007f499044572b in QAbstractItemView::viewportEvent(QEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#24 0x00007f499048a244 in QTreeView::viewportEvent(QEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#25 0x00007f498fa46f66 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () from /usr/lib64/qt4/libQtCore.so.4
#26 0x00007f498ff50093 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#27 0x00007f498ff54c1a in QApplication::notify(QObject*, QEvent*) () from /usr/lib64/qt4/libQtGui.so.4
#28 0x00007f49917f1948 in KApplication::notify(QObject*, QEvent*) () from /usr/lib64/libkdeui.so.5
#29 0x00007f498fa46dcb in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib64/qt4/libQtCore.so.4

Теж нічого підозрілого, стандартний QTreeView малює себе. Йдемо далі:
#14 0x00007f498aecb2b1 in MessageList::Core::MessageItemPrivate::getTagList() const () from /usr/lib64/libmessagelist.so.4
#15 0x00007f498aecb4da in MessageList::Core::MessageItemPrivate::bestTag() const () from /usr/lib64/libmessagelist.so.4
#16 0x00007f498aecb7ad in MessageList::Core::MessageItem::backgroundColor() const () from /usr/lib64/libmessagelist.so.4
#17 0x00007f498aeef525 in MessageList::Core::ThemeDelegate::paint(QPainter*, QStyleOptionViewItem const&, QModelIndex const&) const () from /usr/lib64/libmessagelist.so.4

Естафетна паличка художника перейшла до делегату. Питаємо, який фоновий колір ставити для мессиджа. Проблема уже тут, але її все ще не видно. Йдемо далі:
#9  0x00007f49880ecb8f in Nepomuk::ResourceData::load() () from /usr/lib64/libnepomuk.so.4
#10 0x00007f49880ece9c in Nepomuk::ResourceData::property(QUrl const&) () from /usr/lib64/libnepomuk.so.4
#11 0x00007f498810054a in Nepomuk::Resource::property(QUrl const&) const () from /usr/lib64/libnepomuk.so.4
#12 0x00007f4988100e99 in Nepomuk::Resource::tags() const () from /usr/lib64/libnepomuk.so.4
#13 0x00007f498aeca9ad in MessageList::Core::MessageItemPrivate::fillTagList() const () from /usr/lib64/libmessagelist.so.4

Розміру проблеми ще не видно, але волосся починає шевелитися. Набираємось сміливості, робимо кілька глибоких вдихів і йдемо до кінця:
#0  0x00007f498f10bee3 in select () from /lib64/libc.so.6
#1  0x00007f498fa6f03a in qt_safe_select(int, fd_set*, fd_set*, fd_set*, timeval const*) () from /usr/lib64/qt4/libQtCore.so.4
#2  0x00007f498e17dfd9 in QNativeSocketEnginePrivate::nativeSelect(int, bool, bool, bool*, bool*) const () from /usr/lib64/qt4/libQtNetwork.so.4
#3  0x00007f498e166c04 in QNativeSocketEngine::waitForReadOrWrite(bool*, bool*, bool, bool, int, bool*) () from /usr/lib64/qt4/libQtNetwork.so.4
#4  0x00007f498e177fc9 in QAbstractSocket::waitForReadyRead(int) () from /usr/lib64/qt4/libQtNetwork.so.4
#5  0x00007f4981895fce in Soprano::Client::ClientConnection::executeQuery(int, QString const&, Soprano::Query::QueryLanguage, QString const&) () from /usr/lib64/libsopranoclient.so.1
#6  0x00007f49818977c5 in Soprano::Client::ClientModel::executeQuery(QString const&, Soprano::Query::QueryLanguage, QString const&) const () from /usr/lib64/libsopranoclient.so.1
#7  0x00007f49880f6bb5 in Nepomuk::MainModel::executeQuery(QString const&, Soprano::Query::QueryLanguage, QString const&) const () from /usr/lib64/libnepomuk.so.4
#8  0x00007f49883dde31 in Soprano::FilterModel::executeQuery(QString const&, Soprano::Query::QueryLanguage, QString const&) const () from /usr/lib64/libsoprano.so.4

Нагадаю: Nepomuk - система керування метаданими, Soprano - об’єктно-орієнтований інтерфейс до метаданих. Виходить що? Виходить що для того щоб визначити колір фону для ячейки треба залізти у СУБД! І так для кожної ячейки! Для кожного paint event!
Поліз у сорси.
ThemeDelegate::paint
  if ( !index.isValid() )                                                                                              
    return; // bleah                                                                                                   
                                                                                                                       
  Item * item = itemFromIndex( index );                                                                                
  if ( !item )                                                                                                         
    return; // hm...                                                                                                   
                                                                                                                       
  QStyleOptionViewItemV4 opt = option;                                                                                 
  initStyleOption( &opt, index );                                                                                      
                                                                                                                       
  opt.text.clear(); // draw no text for me, please.. I'll do it in a while                                             
                                                                                                                       
  // Set background color of control if necessary                                                                      
  if ( item->type() == Item::Message ) {                                                                               
    MessageItem * msgItem = static_cast< MessageItem * >( item );                                                      
    if ( msgItem->backgroundColor().isValid() )                                                                        
      opt.backgroundBrush = QBrush( msgItem->backgroundColor() );                                                      
  } 

Ось цей "дядя з великиму вухами"! Що ж він такого робить у backgroundColor()?
MessageItem::backgroundColor
QColor MessageItem::backgroundColor() const                                                                            
{                                                                                                                      
  Q_D( const MessageItem );                                                                                            
  const Tag *bestTag = d->bestTag();                                                                                   
  if ( bestTag != 0 ) {                                                                                                
    return bestTag->backgroundColor();                                                                                 
  } else {                                                                                                             
    return QColor();                                                                                                   
  }                                                                                                                    
}

MessageItemPrivate::bestTag
const MessageItem::Tag* MessageItemPrivate::bestTag() const                     
{                                                                               
  const MessageItem::Tag *best = 0;                                             
  foreach( const MessageItem::Tag* tag, getTagList() ) {                        
    if ( !best || tag->priority() < best->priority() )                          
      best = tag;                                                               
  }                                                                             
  return best;                                                                  
}

Ну логічно що йому потрібен список тегів.
MessageItemPrivate::getTagList
QList<MessageItem::Tag*> MessageItemPrivate::getTagList() const                 
{                                                                               
  if ( !mTagList )                                                              
    fillTagList();                                                              
                                                                                
  return *mTagList;                                                             
}

Ага! "Ліниве" створення списку. Ну а fillTagList уже лізе в Nepomuk і звідти цей список витягує. Виникає питання: чому список тегів пустий якщо це не перший пейнт?
Ех, мені б трохи зайвого часу, я б цей KMail розкрутив по гвинтикам і пофіксив ці довбані баги (благо, №277399 у мене проявляється регулярно).


PS: вони (LJ) таки полагодили попередній перегляд!
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

madf: (Default)
madf

April 2018

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
2930     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Dec. 24th, 2025 02:48 pm
Powered by Dreamwidth Studios