Bug 237390 - Rekonq extremly slow when typing in addresses into the address field
Summary: Rekonq extremly slow when typing in addresses into the address field
Status: RESOLVED FIXED
Alias: None
Product: rekonq
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: openSUSE Unspecified
: NOR normal
Target Milestone: ---
Assignee: Andrea Diamantini
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-12 15:55 UTC by wuselwu
Modified: 2010-06-05 00:54 UTC (History)
5 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
bookmark file which slows rekonq down (568.27 KB, application/xml)
2010-05-25 19:31 UTC, Mathias Kraus
Details

Note You need to log in before you can comment on or make changes to this bug.
Description wuselwu 2010-05-12 15:55:15 UTC
Version:            (using KDE 4.4.3)
Installed from:    openSUSE RPMs

When trying to typ in a WWW address into Rekonq's address bar, Rekonq is extremly slow (or, to put it better, simply hangs for a few seconds) while entering the "www" part of a typical WWW address. The rest of the URL is accepted as usual.
Comment 1 wuselwu 2010-05-13 11:51:54 UTC
I just found out the reason for this behaviour: Rekonq seems per default to use all search engines as activated in the "web shortcuts" panel to look for the expression the user types into the address field. As "www" is rather generic, this seems to take some time and leads to delays for several seconds (looking like a dead lock to the user). 
This seems rather counter-intuitive to me. Rekonq should
- not hang while querying search engines
- start querying remote search engines only after several letters have been entered, not already after the first one
- "web shortcuts" were associated with shortcuts like "gg" in the adress bar for me. I did not recognize that the search engines are used at once, as soon as letters are entered into the adress bar. This should be somehow clearer. After all, it is a privacy issue as well, as I might not want it that web queries are started at one.
Comment 2 Andreas Pakulat 2010-05-13 18:09:40 UTC
I'd like to add that this also hinders typing urls or doing web-shortcuts as rekonq eats keypresses. As I'm a rather quick typer, especially when searching stuff, I often end up with searching for "fo" on google instead of "foobar" even if I properly hit all keys. I always have to wait for the completion-popup to be shown to make sure the shortcut works (or url is fully taken by rekonq) which is rather tedious.
Comment 3 wuselwu 2010-05-14 08:26:04 UTC
Right now (0.4.68) the address bar seems completely unusable to me. Always using Google when typing in a valid www-URL, then sometime suddenly doubling the "http://"-part, very slow, hangs, etc :(.
Comment 4 Andrea Diamantini 2010-05-14 11:51:45 UTC
Ok, as we are working now about urlbar, let's see if we can fix also this problems.
First, I really cannot reproduce the "www" hangs here and the issues in comment #3.
Second, rekonq does not search on search engines for the word you type until you press enter, but it just list them.
I cannot understand the problem with the "web shortcuts" in comment #1, sorry. I just can say that if you type "gg:kde", rekonq (and koqnueror) search google for kde.

About Andreas's problem: in 0.4.68 we introduced a timer (200 ms) to not flash suggestions while user types. So, that's quite surely the issue.

I'll work on the timer issue pushing 0.4.69 with the first fixes about this and CC'ing this bug, to know if things go smoother.

Regards
Comment 5 wuselwu 2010-05-14 12:06:03 UTC
Thanks for taking care of this problem.

For me the problem is that I really don't know what Rekonq does with the keys I enter into the URL bar. Sometimes the behaviour simply seems inconsistant. Maybe part of the problem is that keypresses are still lost or misinterpreted, as Andreas says in his comment. 

However, this has improved lately. Some strange things I had until a few days ago seem to work now, so I cannot reproduce them right now. I'll keep an eye an it.
Comment 6 Andrea Diamantini 2010-05-14 20:36:07 UTC
commit 6b4f4d69a3c599bc958ccddc5f7ac1c8648a7042
Author: Andrea Diamantini <adjam7@gmail.com>
Date:   Fri May 14 20:24:06 2010 +0200

    This commit should fix a lot of troubles on fast urlbar typing
    so now situation is:
    - first list is shown immediately
    - timer decreases from 200 to 150 ms (less is pretty unuseful, I fear)
    - people who fast type & returnPress have KUriFilter help
    
    Hope this helps :)
    
    As promised,
    CCBUG:237390

diff --git a/src/urlbar/completionwidget.cpp b/src/urlbar/completionwidget.cpp
index 1bb0178..b19b163 100644
--- a/src/urlbar/completionwidget.cpp
+++ b/src/urlbar/completionwidget.cpp
@@ -35,6 +35,7 @@
 #include "application.h"
 #include "urlresolver.h"
 #include "searchengine.h"
+#include "urlbar.h"
 
 // KDE Includes
 #include <KGlobalSettings>
@@ -180,7 +181,8 @@ bool CompletionWidget::eventFilter(QObject *o, QEvent *e)
     if (wid && wid->isAncestorOf(_parent) && isVisible())
     {
         ListItem *child;
-
+        UrlBar *w;
+        
         if (type == QEvent::KeyPress)
         {
             QKeyEvent *ev = static_cast<QKeyEvent *>(e);
@@ -214,12 +216,21 @@ bool CompletionWidget::eventFilter(QObject *o, QEvent *e)
 
             case Qt::Key_Enter:
             case Qt::Key_Return:
-                child = findChild<ListItem *>(QString::number(_currentIndex));
-                emit chosenUrl(child->url(), Rekonq::CurrentTab);
+                w = qobject_cast<UrlBar *>(parent());               
+                if(w->text() == _typedString)
+                {
+                    child = findChild<ListItem *>(QString::number(_currentIndex));
+                    emit chosenUrl(child->url(), Rekonq::CurrentTab);
+                }
+                else
+                {
+                    // this will be used just on fast typing..
+                    emit chosenUrl(KUrl(w->text()), Rekonq::CurrentTab);
+                }
                 ev->accept();
                 hide();
                 return true;
-
+                
             case Qt::Key_Escape:
                 hide();
                 return true;
@@ -259,6 +270,8 @@ void CompletionWidget::itemChosen(ListItem *item, Qt::MouseButton button)
 
 void CompletionWidget::suggestUrls(const QString &text)
 {
+    _typedString = text;
+    
     QWidget *w = qobject_cast<QWidget *>(parent());
     if (!w->hasFocus())
         return;
diff --git a/src/urlbar/completionwidget.h b/src/urlbar/completionwidget.h
index 4ce8248..2d33b59 100644
--- a/src/urlbar/completionwidget.h
+++ b/src/urlbar/completionwidget.h
@@ -85,6 +85,8 @@ private:
     int _currentIndex;
 
     KService::Ptr _searchEngine;
+
+    QString _typedString;
 };
 
 #endif // COMPLETION_WIDGET_H
diff --git a/src/urlbar/listitem.cpp b/src/urlbar/listitem.cpp
index c6f7534..f91840d 100644
--- a/src/urlbar/listitem.cpp
+++ b/src/urlbar/listitem.cpp
@@ -296,6 +296,7 @@ QString SearchListItem::searchItemTitle(QString engine, QString text)
     return QString(i18nc("%1=search engine, e.g. Google, Wikipedia %2=text to search for", "Search %1 for <b>%2</b>", engine, text));
 }
 
+
 void SearchListItem::changeSearchEngine(KService::Ptr engine)
 {
     m_titleLabel->setText(searchItemTitle(engine->name(), m_text));
diff --git a/src/urlbar/urlbar.cpp b/src/urlbar/urlbar.cpp
index fb98076..d2992c4 100644
--- a/src/urlbar/urlbar.cpp
+++ b/src/urlbar/urlbar.cpp
@@ -402,7 +402,7 @@ void UrlBar::detectTypedString(const QString &typed)
     
     if(_suggestionTimer->isActive())
         _suggestionTimer->stop();
-    _suggestionTimer->start(200);
+    _suggestionTimer->start(150);
 }
 
 
diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp
index 12e2f76..840fd78 100644
--- a/src/urlbar/urlresolver.cpp
+++ b/src/urlbar/urlresolver.cpp
@@ -222,7 +222,7 @@ UrlSearchList UrlResolver::bookmarksResolution()
 
 UrlSearchList UrlResolver::placeTypedDomaineNameOnTop(UrlSearchList list)
 {
-    int i=0;
+    int i = 0;
     bool found = false;
 
     while(i<list.count() && !found)
@@ -239,4 +239,3 @@ UrlSearchList UrlResolver::placeTypedDomaineNameOnTop(UrlSearchList list)
     
     return list;
 }
-
Comment 7 Andreas Pakulat 2010-05-14 22:42:31 UTC
Cool, that works quite well already, key events are not eaten anymore. Only (minor) annoyance is that showing the popup still takes a second or so which makes the whole app unresponsive. Both Konqueror and Google-Chrome handle that better, there's no unresponsiveness while they show the popup...
Comment 8 eric 2010-05-23 14:02:19 UTC
I'm using version 0.4.70. The patch in comment #6 was already commited.

But I'm still having the same problem: after typing whatever character, I have to wait 10 seconds (maybe a little bit less).

I've found out that this problem goes away when I delete my bookmark file (~/.kde4/share/apps/konqueror/bookmarks.xml)... this is off course not an acceptable solution.
Comment 9 Andrea Diamantini 2010-05-24 09:44:43 UTC
On Sunday 23 May 2010 14:02:25 eric wrote:
> https://bugs.kde.org/show_bug.cgi?id=237390
> 
> 
> 
> 
> 
> --- Comment #8 from eric <prozac gmx net>  2010-05-23 14:02:19 ---
> I'm using version 0.4.70. The patch in comment #6 was already commited.
> 
> But I'm still having the same problem: after typing whatever character, I
> have to wait 10 seconds (maybe a little bit less).
> 
> I've found out that this problem goes away when I delete my bookmark file
> (~/.kde4/share/apps/konqueror/bookmarks.xml)... this is off course not an
> acceptable solution.

Beh, why not? We can try fixing this, forcing rekonq to delete bookmarks every 
time :D

Kidding, of course. Thanks for noticing this important thing.
Comment 10 eric 2010-05-24 19:17:42 UTC
(In reply to comment #9)
> Beh, why not? We can try fixing this, forcing rekonq to delete bookmarks every 
> time :D
> 
> Kidding, of course. Thanks for noticing this important thing.

I don't know if this is important, but I have a bookmark with normal western characters but also "foreign" characters like chinese.
Comment 11 Mathias Kraus 2010-05-25 19:31:26 UTC
Created attachment 43883 [details]
bookmark file which slows rekonq down
Comment 12 Mathias Kraus 2010-05-25 19:36:22 UTC
above I added a bookmark file with several hundred items. just put it into ~/.kde/share/apps/konqueror, start rekonq and start typing "kde-look". it freezes rekonq for several seconds, at least at my laptop.
I hope it helps.
regards,
mathias
Comment 13 Georges 2010-05-27 19:36:02 UTC
Using version 0.4.90 from git I can also confirm this problem.
The first character I type is shown but then it hangs for about 4s after which it shows the popup with suggestions ... this also if I type only one char.
Comment 14 noinoin 2010-05-28 11:43:20 UTC
I think the problem ist that there is no search index for the bookmarks. It's a plain xml-file so fulltext search will allways be slow. Couldn't the searching be done by nepomuk, which i think keeps an index of the bookmarks?

I have many bookmarks (thousands), if i type a character into the address bar i have to wait like 30 seconds on a fairly fast computer. This should definitely be done in a thread and should use some sort of search index, otherwise it will
allways be to slow for a large enough bookmark collection.

Another solution would be to make configurable or to set a timelimit for the search.
Comment 15 Georges 2010-05-28 12:10:27 UTC
(In reply to comment #14)
> I think the problem ist that there is no search index for the bookmarks. It's a
> plain xml-file so fulltext search will allways be slow. Couldn't the searching
> be done by nepomuk, which i think keeps an index of the bookmarks?
> 
> I have many bookmarks (thousands), if i type a character into the address bar i
> have to wait like 30 seconds on a fairly fast computer. This should definitely
> be done in a thread and should use some sort of search index, otherwise it will
> allways be to slow for a large enough bookmark collection.

Even with thousands of bookmarks it shouldn't be _that_ slow ... just try grep and see how slow it really is :-)
Well when using konqueror it works fine ... so maybe it would be worth to have a look at konqeuror's code


> Another solution would be to make configurable or to set a timelimit for the
> search.

Ah IMHO not really a user friendly solution
Comment 16 Andrea Diamantini 2010-06-05 00:54:02 UTC
commit deab0dd37edbc4007a3c2cf32d31811aff0e7e2d
Author: Andrea Diamantini <adjam7@gmail.com>
Date:   Fri Jun 4 23:21:46 2010 +0200

    Awesome bar speed up
    This commit introduces notable changes and needs a lot of tests
    
    Courtesy patch from Mathias Kraus. Thanks :)
    
    BUG: 237390

diff --git a/src/bookmarks/bookmarksmanager.cpp b/src/bookmarks/bookmarksmanager.cpp
index c430078..93bb538 100644
--- a/src/bookmarks/bookmarksmanager.cpp
+++ b/src/bookmarks/bookmarksmanager.cpp
@@ -203,7 +203,8 @@ QAction * BookmarkMenu::actionForBookmark(const KBookmark &bookmark)
     }
     else
     {
-        Application::bookmarkProvider()->completionObject()->addItem(bookmark.url().url());
+        UrlSearchItem urlSearchItem(UrlSearchItem::Bookmark, bookmark.url().prettyUrl() , bookmark.fullText(), QDateTime(), 1, bookmark.description(), QString());
+        Application::bookmarkProvider()->completionObject()->addItem(urlSearchItem);
         return  new KBookmarkAction(bookmark, owner(), this);
     }
 }
@@ -222,7 +223,6 @@ void BookmarkMenu::refill()
         addAddBookmarksList();
         addNewFolder();
         addEditBookmarks();
-
     }
     else
     {
@@ -270,8 +270,9 @@ BookmarkProvider::BookmarkProvider(QObject *parent)
         , m_bookmarkMenu(0)
         , m_completion(0)
 {
+    kDebug() << "Loading Bookmarks Manager...";
     // take care of the completion object
-    m_completion = new KCompletion;
+    m_completion = new AwesomeUrlCompletion;
     m_completion->setOrder(KCompletion::Weighted);
 
     KUrl bookfile = KUrl("~/.kde/share/apps/konqueror/bookmarks.xml");  // share konqueror bookmarks
@@ -299,6 +300,8 @@ BookmarkProvider::BookmarkProvider(QObject *parent)
     // setup menu
     m_owner = new BookmarkOwner(this);
     connect(m_owner, SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType &)), this, SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType &)));
+
+    kDebug() << "Loading Bookmarks Manager... DONE!";
 }
 
 
@@ -346,6 +349,7 @@ void BookmarkProvider::slotBookmarksChanged(const QString &group, const QString
             fillBookmarkBar(bookmarkToolBar);
         }
     }
+    //TODO: also change completion object
 }
 
 
@@ -379,7 +383,9 @@ void BookmarkProvider::contextMenu(const QPoint &point)
 KActionMenu* BookmarkProvider::bookmarkActionMenu(QWidget *parent)
 {
     KMenu *menu = new KMenu(parent);
+    kDebug() << "new Bookmarks Menu...";
     m_bookmarkMenu = new BookmarkMenu(m_manager, m_owner, menu, m_actionCollection);
+    kDebug() << "new Bookmarks Menu...DONE";
     KActionMenu *bookmarkActionMenu = new KActionMenu(parent);
     bookmarkActionMenu->setMenu(menu);
     bookmarkActionMenu->setText(i18n("&Bookmarks"));
@@ -425,7 +431,7 @@ KBookmarkGroup BookmarkProvider::rootGroup()
 }
 
 
-KCompletion *BookmarkProvider::completionObject() const
+AwesomeUrlCompletion *BookmarkProvider::completionObject() const
 {
     return m_completion;
 }
diff --git a/src/bookmarks/bookmarksmanager.h b/src/bookmarks/bookmarksmanager.h
index ae12280..dfebebd 100644
--- a/src/bookmarks/bookmarksmanager.h
+++ b/src/bookmarks/bookmarksmanager.h
@@ -36,13 +36,13 @@
 
 // Local Includes
 #include "application.h"
+#include "urlresolver.h"
 
 // Qt Includes
 #include <QWidget>
 
 // KDE Includes
 #include <KBookmarkOwner>
-#include <KCompletion>
 
 // Forward Declarations
 class BookmarkProvider;
@@ -226,19 +226,14 @@ public:
      */
     KBookmarkGroup rootGroup();
 
-    KBookmarkManager *bookmarkManager()
-    {
-        return m_manager;
-    }
-    BookmarkOwner *bookmarkOwner()
-    {
-        return m_owner;
-    }
+    inline KBookmarkManager *bookmarkManager() { return m_manager; }
+    
+    inline BookmarkOwner *bookmarkOwner() { return m_owner; }
 
     /**
-    * @returns the KCompletion object.
+    * @returns the AwesomeUrlCompletion object.
     */
-    KCompletion *completionObject() const;
+    AwesomeUrlCompletion *completionObject() const;
 
     QString titleForBookmarkUrl(QString url);
 
@@ -278,7 +273,7 @@ private:
     KActionCollection *m_actionCollection;
     BookmarkMenu *m_bookmarkMenu;
     QList<KToolBar*> m_bookmarkToolBars;
-    KCompletion *m_completion;
+    AwesomeUrlCompletion *m_completion;
 };
 
 
diff --git a/src/history/historymanager.cpp b/src/history/historymanager.cpp
index c0f8793..d531c18 100644
--- a/src/history/historymanager.cpp
+++ b/src/history/historymanager.cpp
@@ -69,8 +69,9 @@ HistoryManager::HistoryManager(QObject *parent)
         , m_historyModel(0)
         , m_historyFilterModel(0)
         , m_historyTreeModel(0)
-        , m_completion(new KCompletion)
+        , m_completion(new AwesomeUrlCompletion)
 {
+    kDebug() << "Loading HistoryManager...";
     // take care of the completion object
     m_completion->setOrder(KCompletion::Weighted);
 
@@ -87,6 +88,7 @@ HistoryManager::HistoryManager(QObject *parent)
 
     // QWebHistoryInterface will delete the history manager
     QWebHistoryInterface::setDefaultInterface(this);
+    kDebug() << "Loading HistoryManager... DONE";
 }
 
 
@@ -131,7 +133,8 @@ void HistoryManager::addHistoryEntry(const QString &url)
     // Add item to completion object
     QString _url(url);
     _url.remove(QRegExp("^http://|/$"));
-    m_completion->addItem(_url);
+    UrlSearchItem urlSearchItem(UrlSearchItem::History, _url, QString(), item.dateTime, 1, QString(), QString());
+    m_completion->addItem(urlSearchItem);
 }
 
 
@@ -251,20 +254,21 @@ void HistoryManager::removeHistoryEntry(const HistoryItem &item)
 
 void HistoryManager::removeHistoryEntry(const KUrl &url, const QString &title)
 {
+    HistoryItem item;
     for (int i = 0; i < m_history.count(); ++i)
     {
         if (url == m_history.at(i).url
                 && (title.isEmpty() || title == m_history.at(i).title))
         {
-            removeHistoryEntry(m_history.at(i));
+            item = m_history.at(i);
+            removeHistoryEntry(item);
             break;
         }
     }
 
     // Remove item from completion object
-    QString _url = url.path();
-    _url.remove(QRegExp("^http://|/$"));
-    m_completion->removeItem(_url);
+    UrlSearchItem urlSearchItem(UrlSearchItem::History, item.url, item.title, item.dateTime, 0, QString(), QString());
+    m_completion->removeItem(urlSearchItem);
 }
 
 
@@ -367,9 +371,10 @@ void HistoryManager::load()
         lastInsertedItem = item;
 
         // Add item to completion object
-        QString _url = item.url;
+        //QString _url = item.url;
         //_url.remove(QRegExp("^http://|/$"));
-        m_completion->addItem(_url);
+        UrlSearchItem urlSearchItem(UrlSearchItem::History, item.url, item.title, item.dateTime, 1, QString(), QString());
+        m_completion->addItem(urlSearchItem);
     }
     if (needToSort)
         qSort(list.begin(), list.end());
@@ -453,7 +458,7 @@ void HistoryManager::save()
 }
 
 
-KCompletion * HistoryManager::completionObject() const
+AwesomeUrlCompletion * HistoryManager::completionObject() const
 {
     return m_completion;
 }
diff --git a/src/history/historymanager.h b/src/history/historymanager.h
index 0f13178..7b82579 100644
--- a/src/history/historymanager.h
+++ b/src/history/historymanager.h
@@ -32,6 +32,7 @@
 
 // Rekonq Includes
 #include "rekonq_defines.h"
+#include "urlresolver.h"
 
 // KDE Includes
 #include <KUrl>
@@ -113,9 +114,6 @@ class HistoryModel;
 class HistoryFilterModel;
 class HistoryTreeModel;
 
-class KCompletion;
-
-
 /**
  * THE History Manager:
  * It manages rekonq history
@@ -155,9 +153,9 @@ public:
     HistoryTreeModel *historyTreeModel() const;
 
     /**
-    * @returns the KCompletion object.
+    * @returns the AwesomeUrlCompletion object.
     */
-    KCompletion *completionObject() const;
+    AwesomeUrlCompletion *completionObject() const;
 
     void addDownload(const QString &srcUrl, const QString &destUrl);
     DownloadList downloads();
@@ -189,7 +187,7 @@ private:
     HistoryTreeModel *m_historyTreeModel;
 
     // the completion object we sync with
-    KCompletion *m_completion;
+    AwesomeUrlCompletion *m_completion;
 };
 
 
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index dc1dc70..805f3d4 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -109,6 +109,7 @@ MainWindow::MainWindow()
         , m_hidePopup(new QTimer(this))
         , m_ac(new KActionCollection(this))
 {
+    kDebug() << "MainWindow ctor...";
     // enable window size "auto-save"
     setAutoSaveSettings();
 
@@ -152,6 +153,8 @@ MainWindow::MainWindow()
     connect(m_hidePopup, SIGNAL(timeout()), m_popup, SLOT(hide()));
 
     QTimer::singleShot(0, this, SLOT(postLaunch()));
+
+    kDebug() << "MainWindow ctor...DONE";
 }
 
 
@@ -185,6 +188,8 @@ MainWindow::~MainWindow()
 
 void MainWindow::setupToolbars()
 {
+    kDebug() << "setup toolbars...";
+    
     // ============ Main ToolBar  ================================
     m_mainBar->addAction(actionByName(KStandardAction::name(KStandardAction::Back)));
     m_mainBar->addAction(actionByName(KStandardAction::name(KStandardAction::Forward)));
@@ -267,6 +272,8 @@ QSize MainWindow::sizeHint() const
 
 void MainWindow::setupActions()
 {
+    kDebug() << "setup actions...";
+    
     // this let shortcuts work..
     actionCollection()->addAssociatedWidget(this);
 
@@ -454,6 +461,7 @@ void MainWindow::setupActions()
 
 void MainWindow::setupTools()
 {
+    kDebug() << "setup tools...";
     KActionMenu *toolsMenu = new KActionMenu(KIcon("configure"), i18n("&Tools"), this);
     toolsMenu->setDelayed(false);
 
@@ -531,6 +539,7 @@ void MainWindow::setupTools()
 
 void MainWindow::setupPanels()
 {
+    kDebug() << "setup panels...";
     KAction* a;
 
     // STEP 1
diff --git a/src/urlbar/listitem.cpp b/src/urlbar/listitem.cpp
index a887841..c0d163c 100644
--- a/src/urlbar/listitem.cpp
+++ b/src/urlbar/listitem.cpp
@@ -212,8 +212,8 @@ PreviewListItem::PreviewListItem(const UrlSearchItem &item, const QString &text,
 
     QLabel *previewLabelIcon = new QLabel(this);
     previewLabelIcon->setFixedSize(45, 33);
-    new PreviewLabel(item.url.url(), 38, 29, previewLabelIcon);
-    IconLabel* icon = new IconLabel(item.url.url(), previewLabelIcon);
+    new PreviewLabel(item.url, 38, 29, previewLabelIcon);
+    IconLabel* icon = new IconLabel(item.url, previewLabelIcon);
     icon->move(27, 16);
     hLayout->addWidget(previewLabelIcon);
 
@@ -223,13 +223,13 @@ PreviewListItem::PreviewListItem(const UrlSearchItem &item, const QString &text,
     QString title = item.title;
     if (title.isEmpty())
     {
-        title = item.url.url();
+        title = item.url;
         title = title.remove("http://");
-	title.truncate(title.indexOf("/"));
+        title.truncate(title.indexOf("/"));
     }
 
     vLayout->addWidget(new TextLabel(title, text, this));
-    vLayout->addWidget(new TextLabel("<i>" + item.url.url() + "</i>", text, this));
+    vLayout->addWidget(new TextLabel("<i>" + item.url + "</i>", text, this));
 
     hLayout->addLayout(vLayout);
 
@@ -278,7 +278,7 @@ SearchListItem::SearchListItem(const UrlSearchItem &item, const QString &text, Q
 
     m_url = SearchEngine::buildQuery(engine, query);
 
-    m_iconLabel = new IconLabel("edit-find", this); //TODO: get the default engine icon
+    m_iconLabel = new IconLabel("edit-find", this); //TODO: get the default engine icon (will be easy in KDE SC 4.5)
     m_titleLabel = new TextLabel(searchItemTitle(engine->name(), query), QString(), this);
     m_engineBar = new EngineBar(engine, parent);
 
@@ -397,8 +397,8 @@ BrowseListItem::BrowseListItem(const UrlSearchItem &item, const QString &text, Q
     QHBoxLayout *hLayout = new QHBoxLayout;
     hLayout->setSpacing(4);
 
-    hLayout->addWidget(new IconLabel(item.url.url(), this));
-    hLayout->addWidget(new TextLabel(item.url.url(), text, this));
+    hLayout->addWidget(new IconLabel(item.url, this));
+    hLayout->addWidget(new TextLabel(item.url, text, this));
     hLayout->addWidget(new TypeIconLabel(item.type, this));
 
     setLayout(hLayout);
diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp
index 7333e30..7131766 100644
--- a/src/urlbar/urlresolver.cpp
+++ b/src/urlbar/urlresolver.cpp
@@ -43,7 +43,7 @@
 #include <QByteArray>
 
 // defines
-#define MAX_ELEMENTS 9
+#define MAX_ELEMENTS 10
 
 
 // NOTE 
@@ -55,12 +55,6 @@
 // 5. "fixhosturifilter"
 
 
-bool UrlSearchItem::operator==(const UrlSearchItem &i) const
-{
-    return url == i.url;
-}
-
-
 // ------------------------------------------------------------------------
 
 
@@ -99,27 +93,31 @@ UrlResolver::UrlResolver(const QString &typedUrl)
 
 UrlSearchList UrlResolver::orderedSearchItems()
 {
-    // NOTE: the logic here is : "we wanna suggest (at least) 9 elements"
-    // so we have (more or less) 3 from first results (1 from QUrl Resolutions, 2 from
-    // default search engines).
-    // There are 6 remaining: if bookmarkResults + historyResults <= 6, catch all, else
-    // catch first 3 results from the two resulting lists :)
-
+    // NOTE 
+    // the logic here is : "we wanna suggest (at least) 10 elements"
+    // so we have (more or less) 2 from first results (1 from QUrl Resolutions, 1 from
+    // search engines).
+    // There are 8 remaining: if bookmarkResults + historyResults <= 8, catch all, else
+    // catch first 4 results from the two resulting lists :)
+
+    QTime myTime;
+    myTime.start();
+    
     UrlSearchList list;
 
     if( _typedString == QL1S("about:") )
     {
-        UrlSearchItem home(UrlSearchItem::Browse, KUrl("about:home"),       QL1S("home") );
+        UrlSearchItem home(UrlSearchItem::Browse, QString("about:home"),       QL1S("home") );
         list << home;
-        UrlSearchItem favs(UrlSearchItem::Browse, KUrl("about:favorites"),  QL1S("favorites") );
+        UrlSearchItem favs(UrlSearchItem::Browse, QString("about:favorites"),  QL1S("favorites") );
         list << favs;
-        UrlSearchItem clos(UrlSearchItem::Browse, KUrl("about:closedTabs"), QL1S("closed tabs") );
+        UrlSearchItem clos(UrlSearchItem::Browse, QString("about:closedTabs"), QL1S("closed tabs") );
         list << clos;
-        UrlSearchItem book(UrlSearchItem::Browse, KUrl("about:bookmarks"),  QL1S("bookmarks") );
+        UrlSearchItem book(UrlSearchItem::Browse, QString("about:bookmarks"),  QL1S("bookmarks") );
         list << book;
-        UrlSearchItem hist(UrlSearchItem::Browse, KUrl("about:history"),    QL1S("history") );
+        UrlSearchItem hist(UrlSearchItem::Browse, QString("about:history"),    QL1S("history") );
         list << hist;
-        UrlSearchItem down(UrlSearchItem::Browse, KUrl("about:downloads"),  QL1S("downloads") );
+        UrlSearchItem down(UrlSearchItem::Browse, QString("about:downloads"),  QL1S("downloads") );
         list << down;
 
         return list;
@@ -136,59 +134,135 @@ UrlSearchList UrlResolver::orderedSearchItems()
         list << qurlFromUserInputResolution();
     }
 
-    
-    int firstResults = list.count();
-    int checkPoint = 9 - firstResults;
-
+    //find the history items that match the typed string
     UrlSearchList historyList = historyResolution();
     UrlSearchItem privileged = privilegedItem(&historyList);
     int historyResults = historyList.count();
     
-    UrlSearchList bookmarksList = bookmarksResolution(); 
+    //find the bookmarks items that match the typed string
+    UrlSearchList bookmarksList = bookmarksResolution();
     if (privileged.type == UrlSearchItem::Undefined)
     {
         privileged = privilegedItem(&bookmarksList);
     }
-    
-    if (privileged.type != UrlSearchItem::Undefined)
+    else if(privileged.type == UrlSearchItem::History && bookmarksList.removeOne(privileged))
     {
-        list.insert(0,privileged);
+        privileged.type |= UrlSearchItem::Bookmark;
     }
-
     int bookmarksResults = bookmarksList.count();
-
-    if (historyResults + bookmarksResults > checkPoint)
+    
+    if (privileged.type != UrlSearchItem::Undefined)
     {
-        historyList = historyList.mid(0, 3);
-        bookmarksList = bookmarksList.mid(0, 3);
+        list.prepend(privileged);
     }
-
-    QList<UrlSearchItem> common;
-
-    foreach(UrlSearchItem i, historyList)
+    
+    int availableEntries = MAX_ELEMENTS - list.count();
+    
+    UrlSearchList commonList;
+    int commonResutls = 0;
+    
+    //prefer items which are history items als well bookmarks item
+    //if there are more than 1000 bookmark results, the performance impact is noticeable
+    if(bookmarksResults < 1000)
     {
-        if (!bookmarksList.contains(i))
+        //add as many items to the common list as there are available entries in the dropdown list
+        UrlSearchItem urlSearchItem;
+        for(int i = 0; i < historyList.count(); i++)
         {
-            list << i;
+            if (bookmarksList.removeOne(historyList.at(i)))
+            {
+                urlSearchItem = historyList.takeAt(i);
+                urlSearchItem.type |= UrlSearchItem::Bookmark;
+                commonList << urlSearchItem;
+                commonResutls++;
+                if(commonResutls >= availableEntries)
+                {
+                    break;
+                }
+            }
         }
-        else
+        
+        commonResutls = commonList.count();
+        if(commonResutls >= availableEntries)
+        {
+            commonList = commonList.mid(0, availableEntries);
+            historyList = UrlSearchList();
+            bookmarksList = UrlSearchList();
+            availableEntries = 0;
+        }
+        else        //remove all items from the history and bookmarks list up to the remaining entries in the dropdown list
         {
-            i.type |= UrlSearchItem::Bookmark;
-            common << i;
+            availableEntries -= commonResutls;
+            if(historyResults >= availableEntries)
+            {
+                historyList = historyList.mid(0, availableEntries);
+            }
+            if(bookmarksResults >= availableEntries)
+            {
+                bookmarksList = bookmarksList.mid(0, availableEntries);
+            }
         }
     }
-
-    foreach(const UrlSearchItem &i, common)
+    else        //if there are too many bookmarks items, remove all items up to the remaining entries in the dropdown list
     {
-        list << i;
-    }
+        
+        if(historyResults >= availableEntries)
+        {
+            historyList = historyList.mid(0, availableEntries);
+        }
+        if(bookmarksResults >= availableEntries)
+        {
+            bookmarksList = bookmarksList.mid(0, availableEntries);
+        }
 
-    foreach(const UrlSearchItem &i, bookmarksList)
+        UrlSearchItem urlSearchItem;
+        for(int i = 0; i < historyList.count(); i++)
+        {
+            if (bookmarksList.removeOne(historyList.at(i)))
+            {
+                urlSearchItem = historyList.takeAt(i);
+                urlSearchItem.type |= UrlSearchItem::Bookmark;
+                commonList << urlSearchItem;
+            }
+        }
+        
+        availableEntries -= commonList.count();
+    }
+    
+    historyResults = historyList.count();
+    bookmarksResults = bookmarksList.count();
+    commonResutls = commonList.count();
+    
+    //now fill the list to MAX_ELEMENTS
+    if(availableEntries > 0)
     {
-        if (!common.contains(i))
-            list << i;
+        int historyEntries = ((int) (availableEntries / 2)) + availableEntries % 2;
+        int bookmarksEntries = availableEntries - historyEntries;
+        
+        if (historyResults >= historyEntries && bookmarksResults >= bookmarksEntries)
+        {
+            historyList = historyList.mid(0, historyEntries);
+            bookmarksList = bookmarksList.mid(0, bookmarksEntries);
+        }
+        else if (historyResults < historyEntries && bookmarksResults >= bookmarksEntries)
+        {
+            if(historyResults + bookmarksResults > availableEntries)
+            {
+                bookmarksList = bookmarksList.mid(0, availableEntries - historyResults);
+            }
+        }
+        else if (historyResults >= historyEntries && bookmarksResults < bookmarksEntries)
+        {
+            if(historyResults + bookmarksResults > availableEntries)
+            {
+                historyList = historyList.mid(0, availableEntries - bookmarksResults);
+            }
+        }
     }
-
+    
+    list = list + historyList + commonList + bookmarksList;
+    qWarning() << "orderedSearchItems leave: " << " elapsed: " << myTime.elapsed();
+    
     return list;
 }
 
@@ -206,7 +280,7 @@ UrlSearchList UrlResolver::qurlFromUserInputResolution()
     if (urlFromUserInput.isValid())
     {
         QString gTitle = i18nc("Browse a website", "Browse");
-        UrlSearchItem gItem(UrlSearchItem::Browse, urlFromUserInput, gTitle);
+        UrlSearchItem gItem(UrlSearchItem::Browse, urlFromUserInput.toString(), gTitle);
         list << gItem;
     }
 
@@ -217,57 +291,166 @@ UrlSearchList UrlResolver::qurlFromUserInputResolution()
 // STEP 2 = Web Searches
 UrlSearchList UrlResolver::webSearchesResolution()
 {
-    return UrlSearchList() << UrlSearchItem(UrlSearchItem::Search, KUrl(), QString());
+    return UrlSearchList() << UrlSearchItem(UrlSearchItem::Search, QString(), QString());
 }
 
 
 // STEP 3 = history completion
 UrlSearchList UrlResolver::historyResolution()
 {
-    UrlSearchList list;
+    AwesomeUrlCompletion *historyCompletion = Application::historyManager()->completionObject();
+    return historyCompletion->substringCompletion(_typedString);
+}
+
+
+// STEP 4 = bookmarks completion
+UrlSearchList UrlResolver::bookmarksResolution()
+{
+    AwesomeUrlCompletion *bookmarkCompletion = Application::bookmarkProvider()->completionObject();
+    return bookmarkCompletion->substringCompletion(_typedString);
+}
+
+
+UrlSearchItem UrlResolver::privilegedItem(UrlSearchList* list)
+{
+    UrlSearchItem item;
+    QString dot;
+    if(!_typedString.endsWith(QL1C('.')))
+    {
+        dot = QString(QL1C('.'));
+    }
+    
+    for(int i = 0; i<list->count(); i++)
+    {
+        item = list->at(i);
+        //kDebug() << item.url.host();
+        //TODO: move this to AwesomeUrlCompletion::substringCompletion and add a priviledged flag to UrlSearchItem
+        if (item.url.contains(_typedString + dot))
+        {
+            list->removeAt(i);
+            return item;
+        }
+    }
+    return UrlSearchItem();
+}
+
+// ------------------------------------------------------------------------------------------------------
+
+
+AwesomeUrlCompletion::AwesomeUrlCompletion()
+{
+    m_resetCompletion = true;
+}
+
+
+AwesomeUrlCompletion::~AwesomeUrlCompletion()
+{
+
+}
+
 
-    KCompletion *historyCompletion = Application::historyManager()->completionObject();
-    QStringList historyResults = historyCompletion->substringCompletion(_typedString);
-    Q_FOREACH(const QString &s, historyResults)
+void AwesomeUrlCompletion::addItem(const UrlSearchItem& itemToAdd)
+{
+    bool match = false;
+    QTime myTime;
+    myTime.start();
+    for(int i = 0; i < m_items.count(); i++)
     {
-        UrlSearchItem it(UrlSearchItem::History, KUrl(s), Application::historyManager()->titleForHistoryUrl(s));
-        list << it;
+        //check if item is already in list; the items are equal if the url and the title are equal
+        if(m_items[i] == itemToAdd)
+        {
+            match = true;
+            //TODO: check what to do if comment or bookmarkPath are different
+            if(m_items[i] < itemToAdd)
+            {
+                m_items[i].visitDateTime = itemToAdd.visitDateTime;
+            }
+            m_items[i].visitCount += itemToAdd.visitCount;
+        }
     }
+    if(!match)
+    {
+        m_items.append(itemToAdd);
+    }
+    m_resetCompletion = true;
+}
 
-    return list;
+
+void AwesomeUrlCompletion::removeItem(const UrlSearchItem& item)
+{
+    m_resetCompletion = m_items.removeOne(item);
 }
 
 
-// STEP 4 = bookmarks completion
-UrlSearchList UrlResolver::bookmarksResolution()
+void AwesomeUrlCompletion::setOrder(KCompletion::CompOrder)
 {
-    UrlSearchList list;
+    //TODO
+}
 
-    KCompletion *bookmarkCompletion = Application::bookmarkProvider()->completionObject();
-    QStringList bookmarkResults = bookmarkCompletion->substringCompletion(_typedString);
-    Q_FOREACH(const QString &s, bookmarkResults)
+
+void AwesomeUrlCompletion::updateTitle(const UrlSearchItem& item, const QString& newTitle)
+{
+    foreach(UrlSearchItem i, m_items)
     {
-        UrlSearchItem it(UrlSearchItem::Bookmark, KUrl(s), Application::bookmarkProvider()->titleForBookmarkUrl(s));
-        list << it;
+        if(i == item)
+        {
+            i.title = newTitle;
+        }
     }
+    m_resetCompletion = true;
+}
 
-    return list;
+
+void AwesomeUrlCompletion::clear()
+{
+    m_items.clear();
+    m_resetCompletion = true;
 }
 
 
-UrlSearchItem UrlResolver::privilegedItem(UrlSearchList* list)
+UrlSearchList AwesomeUrlCompletion::substringCompletion(const QString& completionString)
 {
-    int i=0;
-    while(i<list->count())
+    UrlSearchList* searchList;
+    UrlSearchList tempList;
+    
+    if(!m_resetCompletion)
     {
-        UrlSearchItem item = list->at(i);
-        kDebug() << item.url.host();
-        if (item.url.host().contains( _typedString + QL1C('.') ) )
+        if(completionString.length() <= 1)
         {
-            list->removeAt(i);
-            return item;
+            m_resetCompletion = true;
+        }
+        if(!m_resetCompletion && completionString.length() < m_lastCompletionString.length())
+        {
+            m_resetCompletion = true;
+        }
+        if(!m_resetCompletion && !completionString.startsWith(m_lastCompletionString, Qt::CaseInsensitive))
+        {
+            m_resetCompletion = true;
         }
-        i++;
     }
-    return UrlSearchItem();
+    
+    if(m_resetCompletion)
+    {
+        searchList = &m_items;
+        m_resetCompletion = false;
+    }
+    else
+    {
+        searchList = &m_filteredItems;
+    }
+    
+    Q_FOREACH(const UrlSearchItem &i, *searchList)
+    {
+        //TODO: split string and also search for each word if the are more than one word separated with space
+        if(    i.url.contains(completionString, Qt::CaseInsensitive) 
+            || i.title.contains(completionString, Qt::CaseInsensitive) 
+            || i.description.contains(completionString, Qt::CaseInsensitive)
+          )
+        {
+            tempList.append(i);
+        }
+    }
+    m_lastCompletionString = completionString;
+    m_filteredItems = tempList;
+    return m_filteredItems;
 }
diff --git a/src/urlbar/urlresolver.h b/src/urlbar/urlresolver.h
index 2249ea3..8322814 100644
--- a/src/urlbar/urlresolver.h
+++ b/src/urlbar/urlresolver.h
@@ -33,11 +33,14 @@
 
 // KDE Includes
 #include <KUrl>
+#include <KCompletion>
 
 // Qt Includes
 #include <QString>
 #include <QList>
+#include <QDateTime>
 
+class AwesomeUrlCompletion;
 
 class UrlSearchItem
 {
@@ -53,22 +56,62 @@ public:
     };
 
     int type;
-    KUrl url;
+    QString url;
     QString title;
+    QDateTime visitDateTime;
+    int visitCount;
+    QString description;
+    QString bookmarkPath;
     
-    UrlSearchItem(const UrlSearchItem &item)
-    : type(item.type), url(item.url), title(item.title)
+    UrlSearchItem(const UrlSearchItem &item) : type(item.type),
+                                               url(item.url),
+                                               title(item.title),
+                                               visitDateTime(item.visitDateTime),
+                                               visitCount(item.visitCount),
+                                               description(item.description),
+                                               bookmarkPath(item.bookmarkPath)
     {};
     
-    UrlSearchItem()
-    : type(UrlSearchItem::Undefined), url(KUrl()), title("")
+    UrlSearchItem() : type(UrlSearchItem::Undefined),
+                      url(QString()),
+                      title(QString()),
+                      visitDateTime(QDateTime()),
+                      visitCount(0),
+                      description(QString()),
+                      bookmarkPath(QString())
     {};
     
-    UrlSearchItem(const int &_type, const KUrl &_url, const QString &_title = QString())
-            : type(_type), url(_url), title(_title)
+    UrlSearchItem(const int &_type,
+                  const QString &_url,
+                  const QString &_title = QString(),
+                  const QDateTime &visitDateTime  = QDateTime(),
+                  const int       &visitCount     = 0,
+                  const QString   &description    = QString(),
+                  const QString   &bookmarkPath   = QString()
+                  )
+                  : type(_type),
+                  url(_url),
+                  title(_title),
+                  visitDateTime(visitDateTime),
+                  visitCount(visitCount),
+                  description(description),
+                  bookmarkPath(bookmarkPath)
     {};
 
-    bool operator==(const UrlSearchItem &i) const;
+    inline bool operator==(const UrlSearchItem &i) const
+    {
+        return i.url == url;//TODO && i.title == title;
+    }
+    
+    inline bool operator <(const UrlSearchItem &i) const
+    {
+        return visitDateTime < i.visitDateTime;
+    }
+    
+    inline bool operator >(const UrlSearchItem &i) const
+    {
+        return visitDateTime > i.visitDateTime;
+    }
 };
 
 typedef QList <UrlSearchItem> UrlSearchList;
@@ -96,4 +139,29 @@ private:
     static QRegExp _browseRegexp;
 };
 
+// ------------------------------------------------------------------------------
+
+
+/**
+ * This class represents all searchable item for the awesomebar.
+ */
+class AwesomeUrlCompletion// : public KCompletion
+{
+public:
+    AwesomeUrlCompletion();
+    ~AwesomeUrlCompletion();
+    void addItem(const UrlSearchItem& item);
+    void removeItem(const UrlSearchItem& item);
+    void setOrder(KCompletion::CompOrder);
+    void updateTitle(const UrlSearchItem& item, const QString& newTitle);
+    void clear();
+    UrlSearchList substringCompletion(const QString& completionString);
+    
+private:
+    UrlSearchList m_items;
+    UrlSearchList m_filteredItems;
+    bool m_resetCompletion;
+    QString m_lastCompletionString;
+};
+
 #endif // URL_RESOLVER_H