--- a/application.cpp
+++ b/application.cpp
@@ -25,6 +25,7 @@
 #include <QApplication>
 #include <QMessageBox>
 #include <QDir>
+#include <QDesktopWidget>
 
 #include "libupnpp/upnpplib.hxx"
 #include "libupnpp/log.hxx"
@@ -68,7 +69,40 @@
 #define deleteZ(X) {delete X; X = 0;}
 #endif
 
-#define CONNECT(a,b,c,d) m_app->connect(a, SIGNAL(b), c, SLOT(d), \
+int Application::horizontalDPI;
+
+class Application::Internal {
+public:
+    Internal(QApplication *qapp)
+        : m_app(qapp) {}
+    
+    GUI_Player   *m_player{0};
+    std::shared_ptr<Playlist> m_playlist;
+    DirBrowser   *m_cdb{0};
+
+    UPnPClient::MRDH    m_rdr;
+    RenderingControlQO *m_rdco{0};
+    AVTPlayer    *m_avto{0};
+    OHTimeQO     *m_ohtmo{0};
+    OHVolumeQO   *m_ohvlo{0};
+    OHProductQO  *m_ohpro{0};
+    
+    GUI_Playlist *m_ui_playlist{0};
+    SongcastTool *m_sctool{0};
+    UpplayNotifications *m_notifs{0};
+    
+    CSettingsStorage *m_settings{0};
+    QApplication     *m_app;
+
+    bool             m_initialized{false};
+    // Can we send titles into the playlist (e.g. not OHradio).
+    bool             m_playlistIsPlaylist{false};
+    OHProductQO::SourceType m_ohsourcetype{OHProductQO::OHPR_SourceUnknown};
+    QString          m_renderer_friendly_name;
+};
+
+
+#define CONNECT(a,b,c,d) m->m_app->connect(a, SIGNAL(b), c, SLOT(d), \
                                         Qt::UniqueConnection)
 
 static UPPrefs g_prefs;
@@ -102,31 +136,31 @@
 
 
 Application::Application(QApplication* qapp, QObject *parent)
-    : QObject(parent), m_player(0), m_cdb(0), m_rdco(0),
-      m_avto(0), m_ohtmo(0), m_ohvlo(0), m_ohpro(0),
-      m_ui_playlist(0), m_sctool(0), m_notifs(0), m_settings(0), m_app(qapp),
-      m_initialized(false), m_playlistIsPlaylist(false),
-      m_ohsourcetype(OHProductQO::OHPR_SourceUnknown)
-{
-    m_settings = CSettingsStorage::getInstance();
+    : QObject(parent)
+{
+    m = new Internal(qapp);
+    m->m_settings = CSettingsStorage::getInstance();
 
     QString version = UPPLAY_VERSION;
-    m_settings->setVersion(version);
-
-    m_player = new GUI_Player(this);
-    g_prefs.setParent(m_player);
-    m_player->enableSourceSelect(false);
+    m->m_settings->setVersion(version);
+
+    QWidget *window = QApplication::desktop()->screen();
+    horizontalDPI = window->logicalDpiX(); 
+
+    m->m_player = new GUI_Player(this);
+    g_prefs.setParent(m->m_player);
+    m->m_player->enableSourceSelect(false);
     
-    m_ui_playlist = new GUI_Playlist(m_player->getParentOfPlaylist(), 0);
-    m_player->setPlaylistWidget(m_ui_playlist);
-
-    m_cdb = new DirBrowser(m_player->getParentOfLibrary(), 0);
-    m_player->setLibraryWidget(m_cdb);
-
-    m_notifs = new UpplayNotifications(this);
+    m->m_ui_playlist = new GUI_Playlist(m->m_player->getParentOfPlaylist(), 0);
+    m->m_player->setPlaylistWidget(m->m_ui_playlist);
+
+    m->m_cdb = new DirBrowser(m->m_player->getParentOfLibrary(), 0);
+    m->m_player->setLibraryWidget(m->m_cdb);
+
+    m->m_notifs = new UpplayNotifications(this);
 
     init_connections();
-    string uid = qs2utf8s(m_settings->getPlayerUID());
+    string uid = qs2utf8s(m->m_settings->getPlayerUID());
     if (uid.empty()) {
         QTimer::singleShot(0, this, SLOT(chooseRenderer()));
     } else {
@@ -136,27 +170,28 @@
         }
     }
 
-    m_player->setWindowTitle("Upplay " + version);
-    m_player->setWindowIcon(QIcon(Helper::getIconPath("logo.png")));
-    m_player->setPlaylist(m_ui_playlist);
-    m_player->setStyle(m_settings->getPlayerStyle());
-    m_player->show();
-
-    m_ui_playlist->resize(m_player->getParentOfPlaylist()->size());
-
-    m_player->ui_loaded();
-
-    m_initialized = true;
+    m->m_player->setWindowTitle("Upplay " + version);
+    m->m_player->setWindowIcon(QIcon(Helper::getIconPath("logo.png")));
+    m->m_player->setPlaylist(m->m_ui_playlist);
+    m->m_player->setStyle(m->m_settings->getPlayerStyle());
+    m->m_player->show();
+
+    m->m_ui_playlist->resize(m->m_player->getParentOfPlaylist()->size());
+
+    m->m_player->ui_loaded();
+
+    onPrefsChanged();
+    m->m_initialized = true;
 }
 
 Application::~Application()
 {
-    delete m_player;
+    delete m->m_player;
 }
 
 bool Application::is_initialized()
 {
-    return m_initialized;
+    return m->m_initialized;
 }
 
 void Application::chooseRenderer()
@@ -173,7 +208,7 @@
     QSettings settings;
     bool ohonly = settings.value("ohonly").toBool();
 
-    RenderChooseDLG dlg(m_player);
+    RenderChooseDLG dlg(m->m_player);
     if (ohonly) {
         dlg.setWindowTitle(tr("Select Renderer (OpenHome Only)"));
     }
@@ -191,7 +226,7 @@
         }
         filtered_devices.push_back(&(*it));
         QString fname = u8s2qs(it->friendlyName);
-        if (!m_renderer_friendly_name.compare(fname)) {
+        if (!m->m_renderer_friendly_name.compare(fname)) {
             QListWidgetItem *item = new QListWidgetItem(fname);
             QFont font = dlg.rndsLW->font();
             font.setBold(true);
@@ -214,30 +249,30 @@
 
     UPnPDeviceDesc& chosen(*filtered_devices[row]);
     MetaDataList curmeta;
-    if (m_playlist) {
-        m_playlist->get_metadata(curmeta);
-    }
-
-    m_renderer_friendly_name = u8s2qs(chosen.friendlyName);
+    if (m->m_playlist) {
+        m->m_playlist->get_metadata(curmeta);
+    }
+
+    m->m_renderer_friendly_name = u8s2qs(chosen.friendlyName);
     if (!setupRenderer(chosen.UDN)) {
         QMessageBox::warning(0, "Upplay", tr("Can't connect to ") +
-                             m_renderer_friendly_name);
-        m_renderer_friendly_name = "";
-        return;
-    }
-    m_settings->setPlayerUID(u8s2qs(chosen.UDN));
-
-    if (m_playlist && !dlg.keepRB->isChecked()) {
+                             m->m_renderer_friendly_name);
+        m->m_renderer_friendly_name = "";
+        return;
+    }
+    m->m_settings->setPlayerUID(u8s2qs(chosen.UDN));
+
+    if (m->m_playlist && !dlg.keepRB->isChecked()) {
         if (dlg.replRB->isChecked()) {
-            m_playlist->psl_clear_playlist();
-        }
-        m_playlist->psl_add_tracks(curmeta);
+            m->m_playlist->psl_clear_playlist();
+        }
+        m->m_playlist->psl_add_tracks(curmeta);
     }
 }
 
 void Application::chooseSource()
 {
-    if (m_ohpro) {
+    if (m->m_ohpro) {
         chooseSourceOH();
     } else {
         // Not ready yet
@@ -249,15 +284,15 @@
 void Application::chooseSourceOH()
 {
     vector<UPnPClient::OHProduct::Source> srcs;
-    if (!m_ohpro->getSources(srcs)) {
+    if (!m->m_ohpro->getSources(srcs)) {
         return;
     }
     qDebug() << "Application::chooseSource: got " << srcs.size() << " sources";
     int cur = -1;
-    m_ohpro->sourceIndex(&cur);
+    m->m_ohpro->sourceIndex(&cur);
 
     vector<int> rowtoidx;
-    SourceChooseDLG dlg(m_player);
+    SourceChooseDLG dlg(m->m_player);
     for (unsigned int i = 0; i < srcs.size(); i++) {
         // Receiver can't be usefully selected (no way to specify the
         // sender). Old versions of upmpdcli made Receiver not
@@ -288,7 +323,7 @@
     }
     int idx = rowtoidx[row];
     if (idx != cur) {
-        m_ohpro->setSourceIndex(idx);
+        m->m_ohpro->setSourceIndex(idx);
     }
 }
 
@@ -297,26 +332,26 @@
 void Application::chooseSourceAVT()
 {
     vector<int> rowtoidx;
-    SourceChooseDLG dlg(m_player);
+    SourceChooseDLG dlg(m->m_player);
     dlg.rndsLW->addItem("Playlist");
     dlg.rndsLW->addItem("Radio");
     if (!dlg.exec()) {
         return;
     }
     int row = dlg.rndsLW->currentRow();
-    if (m_playlist) {
-        m_playlist->psl_stop();
-    }
-    m_player->stopped();
+    if (m->m_playlist) {
+        m->m_playlist->psl_stop();
+    }
+    m->m_player->stopped();
     if (row == 1) {
         QString fn = QDir(Helper::getSharePath()).filePath("radiolist.xml");
-        m_playlist = shared_ptr<Playlist>(new PlaylistLOCRD(m_avto,
+        m->m_playlist = shared_ptr<Playlist>(new PlaylistLOCRD(m->m_avto,
                                                             fn.toLocal8Bit()));
-        m_playlistIsPlaylist = false;
+        m->m_playlistIsPlaylist = false;
     } else {
-        m_playlist = shared_ptr<Playlist>(new PlaylistAVT(m_avto,
-                                                          m_rdr->desc()->UDN));
-        m_playlistIsPlaylist = true;
+        m->m_playlist = shared_ptr<Playlist>(new PlaylistAVT(m->m_avto,
+                                                          m->m_rdr->desc()->UDN));
+        m->m_playlistIsPlaylist = true;
     }
     playlist_connections();
 }
@@ -324,12 +359,12 @@
 void Application::openSongcast()
 {
     SongcastDLG *scdlg;
-    if (!m_sctool) {
-        scdlg = new SongcastDLG(m_player);
-        m_sctool = new SongcastTool(scdlg, this);
+    if (!m->m_sctool) {
+        scdlg = new SongcastDLG(m->m_player);
+        m->m_sctool = new SongcastTool(scdlg, this);
     } else {
-        scdlg = m_sctool->dlg();
-        m_sctool->initControls();
+        scdlg = m->m_sctool->dlg();
+        m->m_sctool->initControls();
     }
     if (scdlg) {
         scdlg->hide();
@@ -339,22 +374,22 @@
 
 void Application::clear_renderer()
 {
-    m_rdr = UPnPClient::MRDH();
-    deleteZ(m_rdco);
-    deleteZ(m_avto);
-    deleteZ(m_ohtmo);
-    deleteZ(m_ohvlo);
-    deleteZ(m_ohpro);
-    m_ohsourcetype = OHProductQO::OHPR_SourceUnknown;
+    m->m_rdr = UPnPClient::MRDH();
+    deleteZ(m->m_rdco);
+    deleteZ(m->m_avto);
+    deleteZ(m->m_ohtmo);
+    deleteZ(m->m_ohvlo);
+    deleteZ(m->m_ohpro);
+    m->m_ohsourcetype = OHProductQO::OHPR_SourceUnknown;
 }
 
 void Application::reconnectOrChoose()
 {
-    string uid = qs2utf8s(m_settings->getPlayerUID());
+    string uid = qs2utf8s(m->m_settings->getPlayerUID());
     if (uid.empty() || !setupRenderer(uid)) {
         clear_renderer();
-        m_playlist = shared_ptr<Playlist>(new PlaylistNULL());
-        m_playlistIsPlaylist = false;
+        m->m_playlist = shared_ptr<Playlist>(new PlaylistNULL());
+        m->m_playlistIsPlaylist = false;
         playlist_connections();
         if (QMessageBox::warning(0, "Upplay",
                                  tr("Connection to current rendererer lost. "
@@ -376,77 +411,77 @@
     // providing handles to the services. Note that the lib will
     // return anything implementing either renderingcontrol or
     // ohproduct
-    m_rdr = getRenderer(uid, false);
-    if (!m_rdr) {
+    m->m_rdr = getRenderer(uid, false);
+    if (!m->m_rdr) {
         cerr << "Renderer " << uid << " not found" << endl;
         return false;
     }
-    m_renderer_friendly_name = u8s2qs(m_rdr->desc()->friendlyName);
+    m->m_renderer_friendly_name = u8s2qs(m->m_rdr->desc()->friendlyName);
 
     bool needavt = true;
-    OHPRH ohpr = m_rdr->ohpr();
+    OHPRH ohpr = m->m_rdr->ohpr();
     if (ohpr) {
         // This is an OpenHome media renderer
-        m_ohpro = new OHProductQO(ohpr);
-        connect(m_ohpro, SIGNAL(sourceTypeChanged(OHProductQO::SourceType)),
-                this, SLOT(onSourceTypeChanged(OHProductQO::SourceType)));
+        m->m_ohpro = new OHProductQO(ohpr);
+        connect(m->m_ohpro, SIGNAL(sourceTypeChanged(int)),
+                this, SLOT(onSourceTypeChanged(int)));
 
         // Try to use the time service
-        OHTMH ohtm = m_rdr->ohtm();
+        OHTMH ohtm = m->m_rdr->ohtm();
         if (ohtm) {
             qDebug() << "Application::setupRenderer: OHTm ok, no need for avt";
-            m_ohtmo = new OHTimeQO(ohtm);
+            m->m_ohtmo = new OHTimeQO(ohtm);
             // no need for AVT then
             needavt = false;
         }
 
         // Create appropriate Playlist object depending on type of
-        // source. Some may need m_ohtmo, so keep this behind its
+        // source. Some may need m->m_ohtmo, so keep this behind its
         // creation
         createPlaylistForOpenHomeSource();
         needs_playlist = false;
 
         // Move this out of the if when avt radio is ready
-        m_player->enableSourceSelect(true);
+        m->m_player->enableSourceSelect(true);
     } else {
-        m_player->enableSourceSelect(false);
+        m->m_player->enableSourceSelect(false);
     }
 
     // It would be possible in theory to be connected to an openhome
     // playlist without a time service?? and use avt for time updates
     // instead.
     if (needavt) {
-        AVTH avt = m_rdr->avt();
+        AVTH avt = m->m_rdr->avt();
         if (!avt) {
             qDebug() << "Renderer: AVTransport missing but we need it";
             return false;
         }
-        m_avto = new AVTPlayer(avt);
+        m->m_avto = new AVTPlayer(avt);
     }
 
     // Keep this after avt object creation !
     if (needs_playlist) {
         qDebug() <<"Application::setupRenderer: using AVT playlist";
-        m_playlist = shared_ptr<Playlist>(new PlaylistAVT(m_avto,
-                                                         m_rdr->desc()->UDN));
-        m_playlistIsPlaylist = true;
+        m->m_playlist = shared_ptr<Playlist>(new PlaylistAVT(m->m_avto,
+                                                         m->m_rdr->desc()->UDN));
+        m->m_playlistIsPlaylist = true;
     }
 
 
     // Use either renderingControl or ohvolume for volume control.
-    RDCH rdc = m_rdr->rdc();
+    RDCH rdc = m->m_rdr->rdc();
     if (rdc) {
         qDebug() << "Application::setupRenderer: using Rendering Control";
-        m_rdco = new RenderingControlQO(rdc);
+        m->m_rdco = new RenderingControlQO(rdc);
     } else {
-        OHVLH ohvl = m_rdr->ohvl();
+        OHVLH ohvl = m->m_rdr->ohvl();
         if (!ohvl) {
             qDebug() << "Device implements neither RenderingControl nor "
                 "OHVolume";
             return false;
         }
         qDebug() << "Application::setupRenderer: using OHVolume";
-        m_ohvlo =  new OHVolumeQO(ohvl);
+        m->m_ohvlo =  new OHVolumeQO(ohvl);
     }
     
     renderer_connections();
@@ -457,59 +492,59 @@
 
 void Application::createPlaylistForOpenHomeSource()
 {
-    m_ohsourcetype = m_ohpro->getSourceType();
-
-    switch (m_ohsourcetype) {
+    m->m_ohsourcetype = OHProductQO::SourceType(m->m_ohpro->getSourceType());
+
+    switch (m->m_ohsourcetype) {
 
     case OHProductQO::OHPR_SourceRadio:
     {
-        OHRDH ohrd = m_rdr->ohrd();
+        OHRDH ohrd = m->m_rdr->ohrd();
         if (!ohrd) {
             qDebug() << "Application::createPlaylistForOpenHomeSource: "
                 "radio mode, but can't connect";
             return;
         }
-        OHIFH ohif = m_rdr->ohif();
-        m_playlist = shared_ptr<Playlist>(
+        OHIFH ohif = m->m_rdr->ohif();
+        m->m_playlist = shared_ptr<Playlist>(
             new PlaylistOHRD(new OHRad(ohrd), ohif ? new OHInf(ohif) : 0));
-        m_playlistIsPlaylist = false;
+        m->m_playlistIsPlaylist = false;
     }
     break;
 
     case OHProductQO::OHPR_SourceReceiver:
     {
-        OHRCH ohrc = m_rdr->ohrc();
+        OHRCH ohrc = m->m_rdr->ohrc();
         if (!ohrc) {
             qDebug() << "Application::createPlaylistForOpenHomeSource: "
                 "receiver mode, but can't connect";
             return;
         }
-        m_playlist = shared_ptr<Playlist>(
-            new PlaylistOHRCV(ohrc, u8s2qs(m_rdr->desc()->friendlyName)));
-        m_playlistIsPlaylist = false;
+        m->m_playlist = shared_ptr<Playlist>(
+            new PlaylistOHRCV(ohrc, u8s2qs(m->m_rdr->desc()->friendlyName)));
+        m->m_playlistIsPlaylist = false;
     }
     break;
 
     case OHProductQO::OHPR_SourcePlaylist:
     {
-        OHPLH ohpl = m_rdr->ohpl();
+        OHPLH ohpl = m->m_rdr->ohpl();
         if (ohpl) {
-            m_playlist = shared_ptr<Playlist>(
-                new PlaylistOHPL(new OHPlayer(ohpl), m_ohtmo));
-            m_playlistIsPlaylist = true;
+            m->m_playlist = shared_ptr<Playlist>(
+                new PlaylistOHPL(new OHPlayer(ohpl), m->m_ohtmo));
+            m->m_playlistIsPlaylist = true;
         }
     }
     break;
 
     default:
     {
-        m_playlist = shared_ptr<Playlist>(new PlaylistNULL());
-        m_playlistIsPlaylist = false;
+        m->m_playlist = shared_ptr<Playlist>(new PlaylistNULL());
+        m->m_playlistIsPlaylist = false;
     }
     break;
     }
 
-    if (!m_playlist) {
+    if (!m->m_playlist) {
         qDebug() << "Application::createPlaylistForOpenHomeSource: "
             "could not create playlist object";
     }
@@ -520,15 +555,15 @@
     g_prefs.onShowPrefs(UPPrefs::PTAB_DIRSORT);
 }
 
-void Application::onSourceTypeChanged(OHProductQO::SourceType tp)
+void Application::onSourceTypeChanged(int tp)
 {
     //qDebug() << "Application::onSourceTypeChanged: " << int(tp);
-    if (tp == m_ohsourcetype) {
+    if (tp == m->m_ohsourcetype) {
         //qDebug() << "Application::onSourceTypeChanged: same type";
         return;
     }
     
-    if (!m_ohpro) {
+    if (!m->m_ohpro) {
         // Not possible cause ohpro is the sender of this signal.. anyway
         qDebug() <<"Application::onSourceTypeChanged: no OHProduct!!";
         return;
@@ -540,11 +575,11 @@
 void Application::getIdleMeta(MetaData* mdp)
 {
     QString sourcetype;
-    if (m_ohpro) {
+    if (m->m_ohpro) {
         vector<OHProduct::Source> sources;
-        if (m_ohpro->getSources(sources)) {
+        if (m->m_ohpro->getSources(sources)) {
             int idx;
-            if (m_ohpro->sourceIndex(&idx)) {
+            if (m->m_ohpro->sourceIndex(&idx)) {
                 if (idx >= 0 && idx < int(sources.size())) {
                     sourcetype = u8s2qs(sources[idx].name);
                 }
@@ -553,10 +588,10 @@
     }
 
     mdp->title = QString::fromUtf8("Upplay ") + UPPLAY_VERSION;
-    if (m_renderer_friendly_name.isEmpty()) {
+    if (m->m_renderer_friendly_name.isEmpty()) {
         mdp->artist = "No renderer connected";
     } else {
-        mdp->artist = tr("Renderer: ") + m_renderer_friendly_name;
+        mdp->artist = tr("Renderer: ") + m->m_renderer_friendly_name;
         if (!sourcetype.isEmpty()) {
             mdp->artist += QString::fromUtf8(" (") + sourcetype + ")";
         }
@@ -567,70 +602,70 @@
 // set the playlist connections in a separate function
 void Application::playlist_connections()
 {
-    if (m_playlistIsPlaylist)
-        m_cdb->setPlaylist(m_playlist);
+    if (m->m_playlistIsPlaylist)
+        m->m_cdb->setPlaylist(m->m_playlist);
     else
-        m_cdb->setPlaylist(shared_ptr<Playlist>());
+        m->m_cdb->setPlaylist(shared_ptr<Playlist>());
 
     // Use either ohtime or avt for time updates
-    if (m_ohtmo) {
-        CONNECT(m_ohtmo, secsInSongChanged(quint32),
-                m_playlist.get(), onRemoteSecsInSong(quint32));
-        CONNECT(m_ohtmo, secsInSongChanged(quint32),
-                m_notifs, songProgress(quint32));
-    } else if (m_avto) {
-        CONNECT(m_avto, secsInSongChanged(quint32),
-                m_playlist.get(), onRemoteSecsInSong(quint32));
-        CONNECT(m_avto, secsInSongChanged(quint32),
-                m_notifs, songProgress(quint32));
-    }
-
-    CONNECT(m_player, play(), m_playlist.get(), psl_play());
-    CONNECT(m_player, pause(), m_playlist.get(), psl_pause());
-    CONNECT(m_player, stop(), m_playlist.get(), psl_stop());
-    CONNECT(m_player, forward(), m_playlist.get(), psl_forward());
-    CONNECT(m_player, backward(), m_playlist.get(), psl_backward());
-    CONNECT(m_player, sig_load_playlist(), m_playlist.get(), psl_load_playlist());
-    CONNECT(m_player, sig_save_playlist(), m_playlist.get(), psl_save_playlist());
-    CONNECT(m_player, sig_seek(int), m_playlist.get(), psl_seek(int));
-
-    CONNECT(m_playlist.get(), connectionLost(), this, reconnectOrChoose());
-    CONNECT(m_playlist.get(), playlistModeChanged(Playlist_Mode),
-            m_ui_playlist, setPlayerMode(Playlist_Mode));
-    CONNECT(m_playlist.get(), sig_track_metadata(const MetaData&),
-            m_player, update_track(const MetaData&));
-
-    CONNECT(m_playlist.get(), sig_track_metadata(const MetaData&),
-            m_notifs, notify(const MetaData&));
-    CONNECT(m_playlist.get(), sig_stopped(),  m_notifs, onStopped());
-    CONNECT(m_playlist.get(), sig_paused(),  m_notifs, onPaused());
-    CONNECT(m_playlist.get(), sig_playing(),  m_notifs, onPlaying());
-    CONNECT(m_notifs, notifyNeeded(const MetaData&),
-            m_player, onNotify(const MetaData&));
+    if (m->m_ohtmo) {
+        CONNECT(m->m_ohtmo, secsInSongChanged(quint32),
+                m->m_playlist.get(), onRemoteSecsInSong(quint32));
+        CONNECT(m->m_ohtmo, secsInSongChanged(quint32),
+                m->m_notifs, songProgress(quint32));
+    } else if (m->m_avto) {
+        CONNECT(m->m_avto, secsInSongChanged(quint32),
+                m->m_playlist.get(), onRemoteSecsInSong(quint32));
+        CONNECT(m->m_avto, secsInSongChanged(quint32),
+                m->m_notifs, songProgress(quint32));
+    }
+
+    CONNECT(m->m_player, play(), m->m_playlist.get(), psl_play());
+    CONNECT(m->m_player, pause(), m->m_playlist.get(), psl_pause());
+    CONNECT(m->m_player, stop(), m->m_playlist.get(), psl_stop());
+    CONNECT(m->m_player, forward(), m->m_playlist.get(), psl_forward());
+    CONNECT(m->m_player, backward(), m->m_playlist.get(), psl_backward());
+    CONNECT(m->m_player, sig_load_playlist(), m->m_playlist.get(), psl_load_playlist());
+    CONNECT(m->m_player, sig_save_playlist(), m->m_playlist.get(), psl_save_playlist());
+    CONNECT(m->m_player, sig_seek(int), m->m_playlist.get(), psl_seek(int));
+
+    CONNECT(m->m_playlist.get(), connectionLost(), this, reconnectOrChoose());
+    CONNECT(m->m_playlist.get(), playlistModeChanged(Playlist_Mode),
+            m->m_ui_playlist, setPlayerMode(Playlist_Mode));
+    CONNECT(m->m_playlist.get(), sig_track_metadata(const MetaData&),
+            m->m_player, update_track(const MetaData&));
+
+    CONNECT(m->m_playlist.get(), sig_track_metadata(const MetaData&),
+            m->m_notifs, notify(const MetaData&));
+    CONNECT(m->m_playlist.get(), sig_stopped(),  m->m_notifs, onStopped());
+    CONNECT(m->m_playlist.get(), sig_paused(),  m->m_notifs, onPaused());
+    CONNECT(m->m_playlist.get(), sig_playing(),  m->m_notifs, onPlaying());
+    CONNECT(m->m_notifs, notifyNeeded(const MetaData&),
+            m->m_player, onNotify(const MetaData&));
             
-    CONNECT(m_playlist.get(), sig_stopped(),  m_player, stopped());
-    CONNECT(m_playlist.get(), sig_paused(),  m_player, paused());
-    CONNECT(m_playlist.get(), sig_playing(),  m_player, playing());
-    CONNECT(m_playlist.get(), sig_playing_track_changed(int),
-            m_ui_playlist, track_changed(int));
-    CONNECT(m_playlist.get(), sig_playlist_updated(MetaDataList&, int, int),
-            m_ui_playlist, fillPlaylist(MetaDataList&, int, int));
-    CONNECT(m_ui_playlist, selection_min_row(int),
-            m_playlist.get(), psl_selection_min_row(int));
-    CONNECT(m_ui_playlist, playlist_mode_changed(const Playlist_Mode&),
-            m_playlist.get(), psl_change_mode(const Playlist_Mode&));
-    CONNECT(m_ui_playlist, dropped_tracks(const MetaDataList&, int),
-            m_playlist.get(), psl_insert_tracks(const MetaDataList&, int));
-    CONNECT(m_ui_playlist, sig_rows_removed(const QList<int>&, bool),
-            m_playlist.get(), psl_remove_rows(const QList<int>&, bool));
-    CONNECT(m_ui_playlist, sig_sort_tno(),
-            m_playlist.get(), psl_sort_by_tno());
-    CONNECT(m_ui_playlist, row_activated(int),
-            m_playlist.get(), psl_change_track(int));
-    CONNECT(m_ui_playlist, clear_playlist(),
-            m_playlist.get(), psl_clear_playlist());
-
-    m_playlist->update_state();
+    CONNECT(m->m_playlist.get(), sig_stopped(),  m->m_player, stopped());
+    CONNECT(m->m_playlist.get(), sig_paused(),  m->m_player, paused());
+    CONNECT(m->m_playlist.get(), sig_playing(),  m->m_player, playing());
+    CONNECT(m->m_playlist.get(), sig_playing_track_changed(int),
+            m->m_ui_playlist, track_changed(int));
+    CONNECT(m->m_playlist.get(), sig_playlist_updated(MetaDataList&, int, int),
+            m->m_ui_playlist, fillPlaylist(MetaDataList&, int, int));
+    CONNECT(m->m_ui_playlist, selection_min_row(int),
+            m->m_playlist.get(), psl_selection_min_row(int));
+    CONNECT(m->m_ui_playlist, playlist_mode_changed(const Playlist_Mode&),
+            m->m_playlist.get(), psl_change_mode(const Playlist_Mode&));
+    CONNECT(m->m_ui_playlist, dropped_tracks(const MetaDataList&, int),
+            m->m_playlist.get(), psl_insert_tracks(const MetaDataList&, int));
+    CONNECT(m->m_ui_playlist, sig_rows_removed(const QList<int>&, bool),
+            m->m_playlist.get(), psl_remove_rows(const QList<int>&, bool));
+    CONNECT(m->m_ui_playlist, sig_sort_tno(),
+            m->m_playlist.get(), psl_sort_by_tno());
+    CONNECT(m->m_ui_playlist, row_activated(int),
+            m->m_playlist.get(), psl_change_track(int));
+    CONNECT(m->m_ui_playlist, clear_playlist(),
+            m->m_playlist.get(), psl_clear_playlist());
+
+    m->m_playlist->update_state();
 }
 
 // Direct renderer-Player connections (not going through the Playlist):
@@ -638,54 +673,63 @@
 void Application::renderer_connections()
 {
     // Use either ohtime or avt for time updates
-    if (m_ohtmo) {
-        CONNECT(m_ohtmo, secsInSongChanged(quint32),
-                m_player, setCurrentPosition(quint32));
-    } else if (m_avto) {
-        CONNECT(m_avto, secsInSongChanged(quint32),
-                m_player, setCurrentPosition(quint32));
-    }
-    if (m_ohvlo) {
-        CONNECT(m_player, sig_volume_changed(int), m_ohvlo, setVolume(int));
-        CONNECT(m_player, sig_mute(bool), m_ohvlo, setMute(bool));
-        CONNECT(m_ohvlo, volumeChanged(int), m_player, setVolumeUi(int));
-        CONNECT(m_ohvlo, muteChanged(bool), m_player, setMuteUi(bool));
+    if (m->m_ohtmo) {
+        CONNECT(m->m_ohtmo, secsInSongChanged(quint32),
+                m->m_player, setCurrentPosition(quint32));
+    } else if (m->m_avto) {
+        CONNECT(m->m_avto, secsInSongChanged(quint32),
+                m->m_player, setCurrentPosition(quint32));
+    }
+    if (m->m_ohvlo) {
+        CONNECT(m->m_player, sig_volume_changed(int), m->m_ohvlo, setVolume(int));
+        CONNECT(m->m_player, sig_mute(bool), m->m_ohvlo, setMute(bool));
+        CONNECT(m->m_ohvlo, volumeChanged(int), m->m_player, setVolumeUi(int));
+        CONNECT(m->m_ohvlo, muteChanged(bool), m->m_player, setMuteUi(bool));
         // Set up the initial volume from the renderer value
-        m_player->setVolumeUi(m_ohvlo->volume());
-    } else if (m_rdco) {
-        CONNECT(m_player, sig_volume_changed(int), m_rdco, setVolume(int));
-        CONNECT(m_player, sig_mute(bool), m_rdco, setMute(bool));
-        CONNECT(m_rdco, volumeChanged(int), m_player, setVolumeUi(int));
-        CONNECT(m_rdco, muteChanged(bool), m_player, setMuteUi(bool));
+        m->m_player->setVolumeUi(m->m_ohvlo->volume());
+    } else if (m->m_rdco) {
+        CONNECT(m->m_player, sig_volume_changed(int), m->m_rdco, setVolume(int));
+        CONNECT(m->m_player, sig_mute(bool), m->m_rdco, setMute(bool));
+        CONNECT(m->m_rdco, volumeChanged(int), m->m_player, setVolumeUi(int));
+        CONNECT(m->m_rdco, muteChanged(bool), m->m_player, setMuteUi(bool));
         // Set up the initial volume from the renderer value
-        m_player->setVolumeUi(m_rdco->volume());
+        m->m_player->setVolumeUi(m->m_rdco->volume());
     }
 }
 
 void Application::onPrefsChanged()
 {
-    m_cdb->onSortprefs();
-    auto dark = m_settings->getPlayerStyle();
-    m_player->setStyle(dark);
-    float multiplier = QSettings().value("wholeuiscale").toFloat();
-    m_player->setCoverSize(round(80 * multiplier));
-    m_cdb->setStyleSheet(dark);
+    m->m_cdb->onSortprefs();
+    auto dark = m->m_settings->getPlayerStyle();
+    // The point size have been adjusted in the style sheet, and Qt
+    // will deal with the actual DPI for text. But we need to at least
+    // scale the album cover image size. Dealing with the Webkit view
+    // DPI issues is done in dirbrowser.cpp
+    m->m_player->setStyle(dark);
+    float scale = QSettings().value("wholeuiscale").toFloat();
+    if (scale == 0)
+        scale = 1.0;
+    qDebug() << "wholeuiscale: " << scale << " horizontalDPI " << horizontalDPI;
+    float multiplier = (scale * horizontalDPI) / 96.0;
+    m->m_player->setCoverSize(round(80 * multiplier));
+
+    m->m_cdb->setStyleSheet(dark);
 }
 
 // Connections which make sense without a renderer.
 void Application::init_connections()
 {
-    CONNECT(m_player, show_small_playlist_items(bool),
-            m_ui_playlist, psl_show_small_playlist_items(bool));
-    CONNECT(m_player, sig_choose_renderer(), this, chooseRenderer());
-    CONNECT(m_player, sig_open_songcast(), this, openSongcast());
-    CONNECT(m_player, sig_choose_source(), this, chooseSource());
-    CONNECT(m_player, sig_skin_changed(bool), m_cdb, setStyleSheet(bool));
-    CONNECT(m_player, showSearchPanel(bool), m_cdb, showSearchPanel(bool));
-    CONNECT(m_player, sig_preferences(), &g_prefs, onShowPrefs());
+    CONNECT(m->m_player, show_small_playlist_items(bool),
+            m->m_ui_playlist, psl_show_small_playlist_items(bool));
+    CONNECT(m->m_player, sig_choose_renderer(), this, chooseRenderer());
+    CONNECT(m->m_player, sig_open_songcast(), this, openSongcast());
+    CONNECT(m->m_player, sig_choose_source(), this, chooseSource());
+    CONNECT(m->m_player, sig_skin_changed(bool), m->m_cdb, setStyleSheet(bool));
+    CONNECT(m->m_player, showSearchPanel(bool), m->m_cdb, showSearchPanel(bool));
+    CONNECT(m->m_player, sig_preferences(), &g_prefs, onShowPrefs());
     CONNECT(&g_prefs, sig_prefsChanged(), this, onPrefsChanged());
-    CONNECT(m_cdb, sig_next_group_html(QString),
-            m_ui_playlist, psl_next_group_html(QString));
-    CONNECT(m_cdb, sig_sort_order(), this, onDirSortOrder());
-    CONNECT(m_player, sig_sortprefs(), m_cdb, onSortprefs());
-}
+    CONNECT(m->m_cdb, sig_next_group_html(QString),
+            m->m_ui_playlist, psl_next_group_html(QString));
+    CONNECT(m->m_cdb, sig_sort_order(), this, onDirSortOrder());
+    CONNECT(m->m_player, sig_sortprefs(), m->m_cdb, onSortprefs());
+}