Hello community,

here is the log from the commit of package orion for openSUSE:Factory checked 
in at 2018-10-15 09:46:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/orion (Old)
 and      /work/SRC/openSUSE:Factory/.orion.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "orion"

Mon Oct 15 09:46:37 2018 rev:18 rq:641949 version:1.6.5+git~20181007

Changes:
--------
--- /work/SRC/openSUSE:Factory/orion/orion.changes      2018-07-06 
10:45:39.618992982 +0200
+++ /work/SRC/openSUSE:Factory/.orion.new/orion.changes 2018-10-15 
09:47:45.719081961 +0200
@@ -1,0 +2,27 @@
+Sun Oct 07 19:43:27 UTC 2018 - [email protected]
+
+- Update to version 1.6.5+git~20181007:
+  * version 1.6.6
+  * fix header visibility while mouseover player
+  * add player hotkeys
+  * improve player ui
+  * fix some player ui glitches
+  * add channel name to header when playing vod
+  * fix vod reload seeking to correct position
+  * fix QtAV buffering status and seeking at start
+  * fix mpv player position update
+  * replace spacer with vod time label
+  * add option for hardware acceleration
+  * add option for opengl backend
+  * add option for multiple instances
+  * fix wrong usage of beginRemoveRows
+
+-------------------------------------------------------------------
+Sat Oct 06 23:18:48 UTC 2018 - [email protected]
+
+- Update to version 1.6.5+git~20181005:
+  * enable android topbar hiding feature on desktop
+  * fix appveyor (#245)
+  * add example image of color mod
+
+-------------------------------------------------------------------

Old:
----
  orion-1.6.5+git~20180524.tar.xz

New:
----
  orion-1.6.5+git~20181007.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ orion.spec ++++++
--- /var/tmp/diff_new_pack.9136pa/_old  2018-10-15 09:47:47.351080146 +0200
+++ /var/tmp/diff_new_pack.9136pa/_new  2018-10-15 09:47:47.351080146 +0200
@@ -12,12 +12,12 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           orion
-Version:        1.6.5+git~20180524
+Version:        1.6.5+git~20181007
 Release:        0
 Summary:        Twitch stream client using Qt
 License:        GPL-3.0-only

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.9136pa/_old  2018-10-15 09:47:47.387080106 +0200
+++ /var/tmp/diff_new_pack.9136pa/_new  2018-10-15 09:47:47.387080106 +0200
@@ -1,4 +1,4 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/alamminsalo/orion.git</param>
-              <param 
name="changesrevision">eda7f7e0f1802671a819fab605ec29adea22a9c9</param></service></servicedata>
\ No newline at end of file
+              <param 
name="changesrevision">29dfd55c3332dd36b361d7d6dded8b17c28f9159</param></service></servicedata>
\ No newline at end of file

++++++ orion-1.6.5+git~20180524.tar.xz -> orion-1.6.5+git~20181007.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/README.md 
new/orion-1.6.5+git~20181007/README.md
--- old/orion-1.6.5+git~20180524/README.md      2018-05-24 17:25:25.000000000 
+0200
+++ new/orion-1.6.5+git~20181007/README.md      2018-10-07 17:50:22.000000000 
+0200
@@ -87,6 +87,18 @@
 ## Misc
 
 Supports environment variables such as `QT_QUICK_CONTROLS_MATERIAL_ACCENT`, to 
customize UI colors. 
+
+### Example
+
+```
+# linux example, but similar in other OSes
+QT_QUICK_CONTROLS_MATERIAL_BACKGROUND="#00101f" 
QT_QUICK_CONTROLS_MATERIAL_ACCENT="#FF5722" orion
+```
+
+And this looks like:
+
+<img 
src="https://user-images.githubusercontent.com/5585454/42691905-8438a3fe-86b2-11e8-821e-c4a6bbb8ff08.png";
 width="256">
+
 See more on [qt material 
docs](https://doc.qt.io/qt-5/qtquickcontrols2-material.html).
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/appveyor.yml 
new/orion-1.6.5+git~20181007/appveyor.yml
--- old/orion-1.6.5+git~20180524/appveyor.yml   2018-05-24 17:25:25.000000000 
+0200
+++ new/orion-1.6.5+git~20181007/appveyor.yml   2018-10-07 17:50:22.000000000 
+0200
@@ -1,47 +1,72 @@
-# For info about dev tool paths on Appveyor see 
https://www.appveyor.com/docs/build-environment/#pre-installed-software
-
 environment:
   matrix:
-    - platform: x86
-      configuration: release
-    - platform: x64
-      configuration: release
-    - platform: x86
-      configuration: debug
-    - platform: x64
-      configuration: debug
+  - platform: x64
+    configuration: release
+    qt: 5.10
+    cc: VS2017
+    QTDIR: C:\Qt\5.10\msvc2017_64
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+    OPENSSL_DIR: C:\OpenSSL-Win64
+
+  - platform: x86
+    configuration: release
+    qt: 5.10
+    cc: VS2015
+    toolchain_version: 14
+    QTDIR: C:\Qt\5.10\msvc2015
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+    OPENSSL_DIR: C:\OpenSSL-Win32
+
+matrix:
+  fast_finish: false
+
+cache:
+  - C:\projects\AV -> appveyor.yml
+
+init:
+  - set vcarch=%platform%
+  - set arch=%platform%
+  - set CL=/MP
+  - if "%platform%" == "x64" set vcarch=amd64
+  - set VCREDIST=vcredist_%platform%.exe
+  - if %cc%==VS2017 set VCREDIST=vc_redist.%platform%.exe
+  - if %cc%==VS2017 (
+      call "C:\Program Files (x86)\Microsoft Visual 
Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" %vcarch%
+    ) else if not %cc%==MinGW (
+      call "C:\Program Files (x86)\Microsoft Visual Studio 
%toolchain_version%.0\VC\vcvarsall.bat" %vcarch%
+    )
+  - set PATH=%QTDIR%\bin;%PATH%
+  - if %cc%==MinGW set PATH=C:\Qt\Tools\mingw%toolchain_version%_32\bin;%PATH%
+  - echo NUMBER_OF_PROCESSORS=%NUMBER_OF_PROCESSORS%
+  - echo PROCESSOR_IDENTIFIER=%PROCESSOR_IDENTIFIER%
+  - echo QTDIR=%QTDIR%
+  - echo PATH=%PATH%
 
 install:
-  - if %platform%==x86 set QTDIR=C:\Qt\5.9.3\msvc2015
-  - if %platform%==x64 set QTDIR=C:\Qt\5.9.3\msvc2015_64
-  - if %platform%==x86 set PATH=%QTDIR%\bin;C:\Program Files (x86)\Microsoft 
Visual Studio 14.0\VC\bin;C:\Program Files (x86)\Microsoft 
SDKs\Windows\v7.1A\Bin;%PATH%
-  - if %platform%==x64 set PATH=%QTDIR%\bin;C:\Program Files (x86)\Microsoft 
Visual Studio 14.0\VC\bin\amd64;C:\Program Files (x86)\Microsoft 
SDKs\Windows\v7.1A\Bin;%PATH%
-  - set INCLUDE=C:\Program Files (x86)\Microsoft Visual Studio 
14.0\VC\include;C:\Program Files (x86)\Microsoft 
SDKs\Windows\v7.1A\Include;C:\Program Files (x86)\Windows 
Kits\10\Include\10.0.10150.0\ucrt
-  - if %platform%==x86 set LIB=%QTDIR%\lib;C:\Program Files (x86)\Microsoft 
Visual Studio 14.0\VC\lib;C:\Program Files (x86)\Microsoft 
SDKs\Windows\v7.1A\lib;C:\Program Files (x86)\Windows 
Kits\10\Lib\10.0.10150.0\ucrt\x86
-  - if %platform%==x64 set LIB=%QTDIR%\lib;C:\Program Files (x86)\Microsoft 
Visual Studio 14.0\VC\lib\amd64;C:\Program Files (x86)\Microsoft 
SDKs\Windows\v7.1A\lib\x64;C:\Program Files (x86)\Windows 
Kits\10\Lib\10.0.10150.0\ucrt\x64
-  - set VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
-  - if %platform%==x86 set OPENSSL_DIR=C:\OpenSSL-Win32
-  - if %platform%==x64 set OPENSSL_DIR=C:\OpenSSL-Win64
+  - git clone https://github.com/wang-bin/QtAV.git "C:\projects\QtAV"
+  - cd "C:\projects\QtAV" && git submodule update --init
+  - cd "C:\projects" && C:\projects\QtAV\tools\ci\win\install_dep.bat
+  - cd "C:\projects\QtAV"
+  - qmake QtAV.pro "CONFIG+=%configuration%" "CONFIG+=no-examples" 
"CONFIG+=no-tests"
+  - nmake %configuration%
+  - sdk_install.bat
+
+before_build:
+  - echo APPVEYOR_BUILD_FOLDER=%APPVEYOR_BUILD_FOLDER%
+  - cd %APPVEYOR_BUILD_FOLDER%
+  - git submodule update --init
 
 build_script:
-- cmd: >-
-    echo APPVEYOR_BUILD_FOLDER=%APPVEYOR_BUILD_FOLDER%
-
-    cd %APPVEYOR_BUILD_FOLDER%
-
-    qmake orion.pro "CONFIG+=multimedia"
-
-    mkdir libs
-
-    copy /y "%OPENSSL_DIR%\ssleay32.dll" libs
-
-    copy /y "%OPENSSL_DIR%\libeay32.dll" libs
-
-    nmake %configuration%
-
-    %QTDIR%\bin\windeployqt --qmldir src\qml %configuration%\orion.exe
-
-    dir /s
+  - qmake orion.pro "CONFIG+=%configuration%" "CONFIG+=qtav"
+  - mkdir libs
+  - copy /y "%OPENSSL_DIR%\ssleay32.dll" libs
+  - copy /y "%OPENSSL_DIR%\libeay32.dll" libs
+  - nmake %configuration%
+  - windeployqt --qmldir src\qml %configuration%\orion.exe
+  - copy /y %QTDIR%\bin\av*-*.dll %configuration%
+  - copy /y %QTDIR%\bin\sw*-*.dll %configuration%
+  - copy /y %QTDIR%\bin\QtAV*.dll %configuration%
+  - dir /s
 
 after_build:
   - 7z a orion_%configuration%_%platform%_snapshot_%APPVEYOR_REPO_COMMIT%.zip 
. -x!.git
@@ -50,7 +75,7 @@
   - del %configuration%\*.h
   - del %configuration%\*.res
   - if %configuration%==release copy "resources\orion-installer.iss" 
orion-installer.iss
-  - if %configuration%==release "C:\Program Files (x86)\Inno Setup 5\iscc.exe" 
/DPlatform=%platform% /DAdditionalRedist="C:\Program Files (x86)\Microsoft 
Visual Studio 12.0\VC\redist\1033\vcredist_%platform%.exe" 
/F"orion-%configuration%-%platform%" "orion-installer.iss"
+  - if %configuration%==release "C:\Program Files (x86)\Inno Setup 5\iscc.exe" 
/DPlatform=%platform% 
/DAdditionalRedist="%APPVEYOR_BUILD_FOLDER%\%configuration%\%VCREDIST%" 
/F"orion-%configuration%-%platform%" "orion-installer.iss"
 
 artifacts:
   - path: 
orion_$(configuration)_$(platform)_snapshot_$(APPVEYOR_REPO_COMMIT).zip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/orion.pro 
new/orion-1.6.5+git~20181007/orion.pro
--- old/orion-1.6.5+git~20180524/orion.pro      2018-05-24 17:25:25.000000000 
+0200
+++ new/orion-1.6.5+git~20181007/orion.pro      2018-10-07 17:50:22.000000000 
+0200
@@ -13,7 +13,7 @@
 
 TARGET = orion
 
-VERSION = 1.6.5
+VERSION = 1.6.6
 DEFINES += APP_VERSION=\\\"v$$VERSION\\\"
 DEFINES += APP_NAME=\\\"Orion\\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/orion-1.6.5+git~20180524/resources/orion-installer.iss 
new/orion-1.6.5+git~20181007/resources/orion-installer.iss
--- old/orion-1.6.5+git~20180524/resources/orion-installer.iss  2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/resources/orion-installer.iss  2018-10-07 
17:50:22.000000000 +0200
@@ -39,7 +39,6 @@
 Name: "{group}\Orion"; Filename: "{app}\bin\orion.exe"
 
 [Run]
-Filename: "{app}\bin\vcredist_{#Platform}.exe"; Parameters: "/install /passive 
/norestart"
 #ifdef AdditionalRedist
 #define AdditionalRedistProper ExtractFileName(AdditionalRedist)
 Filename: "{app}\AdditionalRedist\{#AdditionalRedistProper}"; Parameters: 
"/install /passive /norestart"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/main.cpp 
new/orion-1.6.5+git~20181007/src/main.cpp
--- old/orion-1.6.5+git~20180524/src/main.cpp   2018-05-24 17:25:25.000000000 
+0200
+++ new/orion-1.6.5+git~20181007/src/main.cpp   2018-10-07 17:50:22.000000000 
+0200
@@ -80,6 +80,33 @@
 
     QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
 
+    // Load app settings
+    SettingsManager::getInstance()->load();
+
+    auto opengl = SettingsManager::getInstance()->opengl().toLower();
+
+    // OpenGL implementation used to render app.
+    // Need to be set before constructing QGuiApplication
+    // http://doc.qt.io/qt-5/qt.html#ApplicationAttribute-enum
+    if (opengl.contains("desktop")) {
+        QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
+    } else if(opengl.contains("software")) {
+        QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
+    } else {
+        QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
+#ifdef QT_OPENGL_DYNAMIC
+        qputenv("QT_OPENGL", "angle");
+#endif
+#ifdef Q_OS_WIN
+        if (opengl.contains("d3d11"))
+            qputenv("QT_ANGLE_PLATFORM", "d3d11");
+        else if (opengl.contains("d3d9"))
+            qputenv("QT_ANGLE_PLATFORM", "d3d9");
+        else if (opengl.contains("warp"))
+            qputenv("QT_ANGLE_PLATFORM", "warp");
+#endif
+    }
+
 #ifndef Q_OS_ANDROID
     QApplication app(argc, argv);
 #else
@@ -97,13 +124,6 @@
     NetworkManager::initialize(engine.networkAccessManager());
 
 #ifndef Q_OS_ANDROID
-    //Single application solution
-    QLockFile 
lockfile(QDir::temp().absoluteFilePath("wz0dPKqHv3vX0BBsUFZt.lock"));
-    if (!lockfile.tryLock(100)) {
-        // Already running
-        return -1;
-    }
-
     QCommandLineParser parser;
     parser.setApplicationDescription("Twitch.tv client");
     parser.addHelpOption();
@@ -148,13 +168,28 @@
     rootContext->setContextProperty("g_games", 
ChannelManager::getInstance()->getGamesModel());
     rootContext->setContextProperty("vodsModel", 
VodManager::getInstance()->getModel());
 
+
+    rootContext->setContextProperty("g_instance", "main");
+
+#ifndef Q_OS_ANDROID
+    //Single application solution
+    QLockFile 
lockfile(QDir::temp().absoluteFilePath("wz0dPKqHv3vX0BBsUFZt.lock"));
+    if (!lockfile.tryLock(100)) {
+        // Already running
+        if (!SettingsManager::getInstance()->multipleInstances()) {
+            return -1;
+        }
+        rootContext->setContextProperty("g_instance", "child");
+    }
+#endif
+
     // Register qml components
     registerQmlComponents(&app);
 
     // Load QML content
     engine.load(QUrl("qrc:/main.qml"));
 
-    // Load app settings
+    // Trigger setting property notifications
     SettingsManager::getInstance()->load();
 
 #ifndef Q_OS_ANDROID
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/orion-1.6.5+git~20180524/src/model/channellistmodel.cpp 
new/orion-1.6.5+git~20181007/src/model/channellistmodel.cpp
--- old/orion-1.6.5+git~20180524/src/model/channellistmodel.cpp 2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/model/channellistmodel.cpp 2018-10-07 
17:50:22.000000000 +0200
@@ -214,14 +214,16 @@
 void ChannelListModel::clearView()
 {
     //Gives a sign to drop all channels from view, without removing them
-    beginRemoveRows(QModelIndex(), 0, channels.size());
-    endRemoveRows();
+    if (!channels.isEmpty()) {
+        beginRemoveRows(QModelIndex(), 0, channels.size() - 1);
+        endRemoveRows();
+    }
 }
 
 void ChannelListModel::clear()
 {
     if (!channels.isEmpty()){
-        beginRemoveRows(QModelIndex(), 0, channels.size());
+        beginRemoveRows(QModelIndex(), 0, channels.size() - 1);
         qDeleteAll(channels);
         channels.clear();
         channelIdIndex.clear();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/model/gamelistmodel.cpp 
new/orion-1.6.5+git~20181007/src/model/gamelistmodel.cpp
--- old/orion-1.6.5+git~20180524/src/model/gamelistmodel.cpp    2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/model/gamelistmodel.cpp    2018-10-07 
17:50:22.000000000 +0200
@@ -118,7 +118,7 @@
 void GameListModel::clear()
 {
     if (!games.isEmpty()){
-        beginRemoveRows(QModelIndex(), 0, games.size());
+        beginRemoveRows(QModelIndex(), 0, games.size() - 1);
         qDeleteAll(games);
         games.clear();
         endRemoveRows();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/orion-1.6.5+git~20180524/src/model/settingsmanager.cpp 
new/orion-1.6.5+git~20181007/src/model/settingsmanager.cpp
--- old/orion-1.6.5+git~20180524/src/model/settingsmanager.cpp  2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/model/settingsmanager.cpp  2018-10-07 
17:50:22.000000000 +0200
@@ -12,13 +12,20 @@
     //Initial values
     mAlert = true;
     mCloseToTray = false;
+    mMultipleInstances = false;
     mAlertPosition = 1;
     mMinimizeOnStartup = false;
     mTextScaleFactor = 1.0;
     mVolumeLevel = 100;
     mOfflineNotifications = false;
     mAccessToken = "";
+#ifdef Q_OS_WIN
+    mOpengl = "angle (d3d9)";
+#else
+    mOpengl = "opengl es";
+#endif
     mQuality = "source";
+    mDecoder = "auto";
     mChatEdge = 1;
     mLightTheme = false;
     mFont = "";
@@ -50,14 +57,26 @@
         setCloseToTray(settings->value("closeToTray").toBool());
     }
 
+    if (settings->contains("multipleInstances")) {
+        setMultipleInstances(settings->value("multipleInstances").toBool());
+    }
+
     if (settings->contains("minimizeOnStartup")) {
         setMinimizeOnStartup(settings->value("minimizeOnStartup").toBool());
     }
 
+    if (settings->contains("opengl")) {
+        setOpengl(settings->value("opengl").toString());
+    }
+
     if (settings->contains("quality")) {
         setQuality(settings->value("quality").toString());
     }
 
+    if (settings->contains("decoder")) {
+        setDecoder(settings->value("decoder").toString());
+    }
+
     if (settings->contains("volumeLevel")) {
         setVolumeLevel(settings->value("volumeLevel").toInt());
     }
@@ -123,6 +142,22 @@
     emit closeToTrayChanged();
 }
 
+bool SettingsManager::multipleInstances() const
+{
+    return mMultipleInstances;
+}
+
+void SettingsManager::setMultipleInstances(bool multipleInstances)
+{
+    if (mMultipleInstances != multipleInstances) {
+        mMultipleInstances = multipleInstances;
+        settings->setValue("multipleInstances", multipleInstances);
+
+        qDebug() << "multipleInstances changed to" << multipleInstances;
+    }
+    emit multipleInstancesChanged();
+}
+
 int SettingsManager::alertPosition() const
 {
     return mAlertPosition;
@@ -231,6 +266,22 @@
     emit textScaleFactorChanged();
 }
 
+QString SettingsManager::opengl() const
+{
+    return mOpengl;
+}
+
+void SettingsManager::setOpengl(const QString &opengl)
+{
+    if (mOpengl != opengl) {
+        mOpengl = opengl;
+        settings->setValue("opengl", opengl);
+
+        qDebug() << "opengl changed to" << opengl;
+    }
+    emit openglChanged();
+}
+
 QString SettingsManager::quality() const
 {
     return mQuality;
@@ -247,6 +298,22 @@
     emit qualityChanged();
 }
 
+QString SettingsManager::decoder() const
+{
+    return mDecoder;
+}
+
+void SettingsManager::setDecoder(const QString &decoder)
+{
+    if (mDecoder != decoder) {
+        mDecoder = decoder;
+        settings->setValue("decoder", decoder);
+
+        qDebug() << "decoder changed to" << decoder;
+    }
+    emit decoderChanged();
+}
+
 QString SettingsManager::accessToken() const
 {
     return mAccessToken;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/model/settingsmanager.h 
new/orion-1.6.5+git~20181007/src/model/settingsmanager.h
--- old/orion-1.6.5+git~20180524/src/model/settingsmanager.h    2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/model/settingsmanager.h    2018-10-07 
17:50:22.000000000 +0200
@@ -12,13 +12,16 @@
 
     Q_PROPERTY(bool alert READ alert WRITE setAlert NOTIFY alertChanged)
     Q_PROPERTY(bool closeToTray READ closeToTray WRITE setCloseToTray NOTIFY 
closeToTrayChanged)
+    Q_PROPERTY(bool multipleInstances READ multipleInstances WRITE 
setMultipleInstances NOTIFY multipleInstancesChanged)
     Q_PROPERTY(int alertPosition READ alertPosition WRITE setAlertPosition 
NOTIFY alertPositionChanged)
     Q_PROPERTY(int volumeLevel READ volumeLevel WRITE setVolumeLevel NOTIFY 
volumeLevelChanged)
     Q_PROPERTY(bool minimizeOnStartup READ minimizeOnStartup WRITE 
setMinimizeOnStartup NOTIFY minimizeOnStartupChanged)
     Q_PROPERTY(int chatEdge READ chatEdge WRITE setChatEdge NOTIFY 
chatEdgeChanged)
     Q_PROPERTY(bool offlineNotifications READ offlineNotifications WRITE 
setOfflineNotifications NOTIFY offlineNotificationsChanged)
     Q_PROPERTY(double textScaleFactor READ textScaleFactor WRITE 
setTextScaleFactor NOTIFY textScaleFactorChanged)
+    Q_PROPERTY(QString opengl READ opengl WRITE setOpengl NOTIFY openglChanged)
     Q_PROPERTY(QString quality READ quality WRITE setQuality NOTIFY 
qualityChanged)
+    Q_PROPERTY(QString decoder READ decoder WRITE setDecoder NOTIFY 
decoderChanged)
     Q_PROPERTY(QString accessToken READ accessToken WRITE setAccessToken 
NOTIFY accessTokenChanged)
     Q_PROPERTY(bool hasAccessToken READ hasAccessToken NOTIFY 
accessTokenChanged)
     Q_PROPERTY(bool lightTheme READ lightTheme WRITE setLightTheme NOTIFY 
lightThemeChanged)
@@ -28,13 +31,16 @@
 
     bool mAlert;
     bool mCloseToTray;
+    bool mMultipleInstances;
     int mAlertPosition;
     int mVolumeLevel;
     bool mMinimizeOnStartup;
     bool mSwapChat;
     bool mOfflineNotifications;
     double mTextScaleFactor;
+    QString mOpengl;
     QString mQuality;
+    QString mDecoder;
     QString mAccessToken;
     int mChatEdge;
     bool mLightTheme;
@@ -54,6 +60,9 @@
     bool closeToTray() const;
     void setCloseToTray(bool closeToTray);
 
+    bool multipleInstances() const;
+    void setMultipleInstances(bool multipleInstances);
+
     int alertPosition() const;
     void setAlertPosition(int alertPosition);
 
@@ -72,9 +81,15 @@
     double textScaleFactor() const;
     void setTextScaleFactor(double textScaleFactor);
 
+    QString opengl() const;
+    void setOpengl(const QString &opengl);
+
     QString quality() const;
     void setQuality(const QString &quality);
 
+    QString decoder() const;
+    void setDecoder(const QString &decoder);
+
     QString accessToken() const;
 
     void setHiDpi(bool dpi);
@@ -93,13 +108,16 @@
 signals:
     void alertChanged();
     void closeToTrayChanged();
+    void multipleInstancesChanged();
     void alertPositionChanged();
     void volumeLevelChanged();
     void minimizeOnStartupChanged();
     void chatEdgeChanged();
     void offlineNotificationsChanged();
     void textScaleFactorChanged();
+    void openglChanged();
     void qualityChanged();
+    void decoderChanged();
     void lightThemeChanged();
     void accessTokenChanged(QString accessToken);
     void fontChanged();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/model/vodlistmodel.cpp 
new/orion-1.6.5+git~20181007/src/model/vodlistmodel.cpp
--- old/orion-1.6.5+git~20180524/src/model/vodlistmodel.cpp     2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/model/vodlistmodel.cpp     2018-10-07 
17:50:22.000000000 +0200
@@ -114,7 +114,7 @@
 void VodListModel::clear()
 {
     if (!vods.isEmpty()){
-        beginRemoveRows(QModelIndex(), 0, vods.size());
+        beginRemoveRows(QModelIndex(), 0, vods.size() - 1);
         qDeleteAll(vods);
         vods.clear();
         endRemoveRows();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/player/mpvobject.cpp 
new/orion-1.6.5+git~20181007/src/player/mpvobject.cpp
--- old/orion-1.6.5+git~20180524/src/player/mpvobject.cpp       2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/player/mpvobject.cpp       2018-10-07 
17:50:22.000000000 +0200
@@ -26,6 +26,7 @@
 #endif
 
     // Make use of the MPV_SUB_API_OPENGL_CB API.
+    mpv::qt::set_option_variant(mpv, "gpu-context", "angle");
     mpv::qt::set_option_variant(mpv, "vo", "opengl-cb");
     //mpv::qt::set_option_variant(mpv, "input-cursor", "no");
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/MpvBackend.qml 
new/orion-1.6.5+git~20181007/src/qml/MpvBackend.qml
--- old/orion-1.6.5+git~20180524/src/qml/MpvBackend.qml 2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/qml/MpvBackend.qml 2018-10-07 
17:50:22.000000000 +0200
@@ -25,6 +25,8 @@
 stop()              -- Stops playback
 seekTo(ms)          -- Seeks to milliseconds in the current source, works only 
on vods
 setVolume(vol)      -- Number between 0 - 100
+getDecoder()        -- Return list of video decoders
+setDecoder(idx)     -- Set video decoder
 
 Signals needed:
 playingResumed()    -- Signaled when playback toggles from paused / stopped to 
playing
@@ -94,7 +96,29 @@
     }
 
     function setVolume(vol) {
-        volume = Math.round(vol)
+        if (Qt.platform.os === "linux")
+            volume = Math.round(Math.log(vol) / Math.log(100))
+        else
+            volume = Math.round(vol)
+    }
+
+    function getDecoder() {
+        var defaultDecoders = []
+        if (Qt.platform.os == "windows") {
+            defaultDecoders = [ "dxva2-copy", "d3d11va-copy", "cuda-copy", 
"no" ]
+        } else if (Qt.platform.os == "osx" || Qt.platform.os == "ios") {
+            defaultDecoders = [ "videotoolbox", "no" ]
+        } else if(Qt.platform.os == "android") {
+            defaultDecoders = [ "mediacodec_embed", "no" ]
+        } else if (Qt.platform.os == "linux") {
+            defaultDecoders = [ "vaapi-copy", "vdpau-copy", "no" ]
+        }
+        return [ "auto" ].concat(defaultDecoders)
+    }
+
+    function setDecoder(idx) {
+        var decoderName = getDecoder()[idx]
+        renderer.setProperty("hwdec", decoderName)
     }
 
     signal playingResumed()
@@ -133,6 +157,16 @@
         renderer.setProperty("volume", volume)
     }
 
+    Timer {
+        id: positionTimer
+        interval: 1000
+        running: false
+        repeat: true
+        onTriggered: {
+            if (root.status === "PLAYING")
+                root.position += 1
+        }
+    }
 
     MpvObject {
         id: renderer
@@ -145,14 +179,17 @@
 
         onPlayingStopped: {
             root.status = "STOPPED"
+            positionTimer.stop()
         }
 
         onPlayingPaused: {
             root.status = "PAUSED"
+            positionTimer.stop()
         }
 
         onPlayingResumed: {
             root.status = "PLAYING"
+            positionTimer.start()
         }
 
         onPositionChanged: {
@@ -170,6 +207,8 @@
 
             if (root.position !== adjustedPosition)
                 root.position = adjustedPosition
+
+            positionTimer.restart()
         }
 
         Component.onCompleted: {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/orion-1.6.5+git~20180524/src/qml/MultimediaBackend.qml 
new/orion-1.6.5+git~20181007/src/qml/MultimediaBackend.qml
--- old/orion-1.6.5+git~20180524/src/qml/MultimediaBackend.qml  2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/qml/MultimediaBackend.qml  2018-10-07 
17:50:22.000000000 +0200
@@ -25,6 +25,8 @@
 stop()              -- Stops playback
 seekTo(pos)         -- Seeks to milliseconds in the current source, works only 
on vods
 setVolume(vol)      -- Number between 0 - 100
+getDecoder()        -- Return list of video decoders
+setDecoder(idx)     -- Set video decoder
 
 Signals needed:
 playingResumed()    -- Signaled when playback toggles from paused / stopped to 
playing
@@ -86,6 +88,15 @@
         volume = Math.round(vol)
     }
 
+    function getDecoder() {
+        var defaultDecoders = []
+        return defaultDecoders
+    }
+
+    function setDecoder(idx) {
+
+    }
+
     signal playingResumed()
     signal playingPaused()
     signal playingStopped()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/OptionsView.qml 
new/orion-1.6.5+git~20181007/src/qml/OptionsView.qml
--- old/orion-1.6.5+git~20180524/src/qml/OptionsView.qml        2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/qml/OptionsView.qml        2018-10-07 
17:50:22.000000000 +0200
@@ -177,6 +177,64 @@
                         checked: Settings.keepOnTop
                         onClicked: Settings.keepOnTop = checked
                     }
+
+                    Switch {
+                        visible: !isMobile()
+                        id: mulipleInstancesOption
+                        text: "Allow multiple instances"
+                        checked: Settings.multipleInstances
+                        onClicked: Settings.multipleInstances = checked
+                    }
+
+                    RowLayout {
+                        width: parent.width
+
+                        OptionCombo {
+                            id: openglOption
+                            text: "OpenGL (needs restart)"
+                            model: {
+                                var opengl = [ ]
+                                if (Qt.platform.os === "windows") {
+                                    opengl = ["angle", "angle (d3d11)", "angle 
(d3d9)", "angle (warp)"]
+                                } else {
+                                    opengl = ["opengl es"]
+                                }
+                                opengl = opengl.concat(["desktop", "software"])
+                                return opengl
+                            }
+                            Layout.fillWidth: true
+                            property var defaultValue
+
+                            onActivated: {
+                                Settings.opengl = model[currentIndex]
+                            }
+
+                            Component.onCompleted: {
+                                defaultValue = Settings.opengl
+                                selectItem(defaultValue)
+                            }
+
+                            function selectItem(name) {
+                                for (var i in model) {
+                                    if (model[i] === name) {
+                                        currentIndex = i;
+                                        return;
+                                    }
+                                }
+                                //None found, attempt to select first item
+                                currentIndex = 0
+                            }
+                        }
+
+                        Button {
+                            text: "Reset"
+                            font.pointSize: 9
+                            onClicked: {
+                                
openglOption.selectItem(openglOption.defaultValue)
+                            }
+                        }
+                    }
+
                 }
             }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/PlayerView.qml 
new/orion-1.6.5+git~20181007/src/qml/PlayerView.qml
--- old/orion-1.6.5+git~20180524/src/qml/PlayerView.qml 2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/qml/PlayerView.qml 2018-10-07 
17:50:22.000000000 +0200
@@ -21,6 +21,8 @@
 import app.orion 1.0
 
 Page {
+    id: root
+
     property int duration: -1
     property var currentChannel
     property var streamMap
@@ -30,10 +32,11 @@
     property int lastSetPosition
     property bool headersVisible: true
 
-    //Android only
     onHeadersVisibleChanged: {
-        if (isMobile() && view.playerVisible) {
+        if (root.visible) {
+           pArea.hoverEnabled = false
             topbar.visible = headersVisible
+           disableTimer.restart()
         }
     }
 
@@ -42,7 +45,6 @@
     //Renderer interface
     property alias renderer: loader.item
 
-    id: root
 
     //Fix minimode header bar
     clip: true
@@ -122,7 +124,7 @@
     function loadAndPlay(){
         var description = setWatchingTitle();
 
-        var start = !isVod ? -1 : seekBar.position
+        var start = !isVod ? -1 : seekBar.value
 
         var url = streamMap[Settings.quality]
 
@@ -211,11 +213,14 @@
     }
 
     function setWatchingTitle(){
-        var description = currentChannel.title
-                + (currentChannel.game ? " playing " + currentChannel.game : 
"")
-                + (isVod ? " (VOD)" : "");
-        setHeaderText(description);
-        return description;
+       var description = ""
+       if (currentChannel) {
+         description = currentChannel.title + (isVod ? ("\r\n" + 
currentChannel.name) : "")
+                 + (currentChannel.game ? " playing " + currentChannel.game : 
"")
+                 + (isVod ? " (VOD)" : "");
+         setHeaderText(description);
+       }
+       return description;
     }
 
     function loadStreams(streams) {
@@ -270,7 +275,9 @@
                     
VodManager.setVodLastPlaybackPosition(root.currentChannel.name, root.curVodId, 
newPos);
                 }
             }
-            seekBar.value = newPos
+            if (!seekBar.pressed) {
+                seekBar.value = newPos
+            }
         }
 
         onPlayingResumed: {
@@ -290,6 +297,88 @@
         }
     }
 
+    Shortcut {
+        sequence: "Space"
+        context: Qt.ApplicationShortcut
+        onActivated: {
+            renderer.togglePause()
+            clickRect.run()
+            pArea.refreshHeaders()
+        }
+    }
+
+    Shortcut {
+        sequence: "0"
+        context: Qt.ApplicationShortcut
+        onActivated: {
+            reloadStream()
+            pArea.refreshHeaders()
+        }
+    }
+
+    Shortcut {
+        sequence: "f"
+        context: Qt.ApplicationShortcut
+        onActivated: {
+            appFullScreen = !appFullScreen
+        }
+    }
+
+    Shortcut {
+        sequence: "Esc"
+        context: Qt.ApplicationShortcut
+        onActivated: {
+            appFullScreen = false
+        }
+    }
+
+    Shortcut {
+        sequence: "m"
+        context: Qt.ApplicationShortcut
+        onActivated: {
+            volumeBtn.toggleMute()
+            pArea.refreshHeaders()
+        }
+    }
+
+    Shortcut {
+        sequence: "Up"
+        context: Qt.ApplicationShortcut
+        onActivated: {
+            volumeSlider.value += 5
+            pArea.refreshHeaders()
+        }
+    }
+
+    Shortcut {
+        sequence: "Down"
+        context: Qt.ApplicationShortcut
+        onActivated: {
+            volumeSlider.value -= 5
+            pArea.refreshHeaders()
+        }
+    }
+
+    Shortcut {
+        sequence: "Right"
+        context: Qt.ApplicationShortcut
+        onActivated: {
+            if (!isVod || seekBar.pressed) return
+            seekBar.seek(seekBar.value + 5)
+            pArea.refreshHeaders()
+        }
+    }
+
+    Shortcut {
+        sequence: "Left"
+        context: Qt.ApplicationShortcut
+        onActivated: {
+            if (!isVod || seekBar.pressed) return
+            seekBar.seek(seekBar.value - 5)
+            pArea.refreshHeaders()
+        }
+    }
+
     Item {
         id: playerArea
         anchors.fill: parent
@@ -328,10 +417,19 @@
         anchors.fill: playerArea
 
         function refreshHeaders(){
-            if (!hideTimer.running)
+            if (!hideTimer.running && !root.headersVisible)
                 root.headersVisible = true
             hideTimer.restart()
         }
+       
+       Timer {
+         id: disableTimer
+         interval: 200
+         running: false
+         onTriggered:{
+           pArea.hoverEnabled = true
+         }
+       }
 
         onVisibleChanged: refreshHeaders()
         onPositionChanged: refreshHeaders()
@@ -346,7 +444,7 @@
 
             Label {
                 id: clickRectIcon
-                text: renderer.status !== "PLAYING" ? "\ue037" : "\ue034"
+                text: ""
                 anchors.centerIn: parent
                 font.family: "Material Icons"
                 font.pointSize: parent.width * 0.5
@@ -356,6 +454,15 @@
                 id: _anim
                 running: false
 
+                onStarted: {
+                    clickRectIcon.text = renderer.status !== "PLAYING" ? 
"\ue037" : "\ue034"
+                }
+
+                onStopped: {
+                    clickRect.opacity = 0
+                    clickRect.width = 0
+                }
+
                 NumberAnimation {
                     target: clickRect
                     property: "width"
@@ -377,19 +484,21 @@
             function run() {
                 _anim.restart()
             }
+
+            function abort() {
+                _anim.stop()
+            }
         }
 
         onClicked: {
             clickRect.run()
-
-            if (root.headersVisible && bottomBar.height > 50)
-                clickTimer.restart()
-            else
-                refreshHeaders()
+            clickTimer.restart()
+            refreshHeaders()
         }
         onDoubleClicked: {
             if (!isMobile()) {
                 clickTimer.stop()
+                clickRect.abort();
                 appFullScreen = !appFullScreen
             }
         }
@@ -400,7 +509,7 @@
         Timer {
             //Dbl click timer
             id: clickTimer
-            interval: 440
+            interval: 200
             repeat: false
             onTriggered: {
                 renderer.togglePause();
@@ -413,8 +522,18 @@
             running: false
             repeat: false
             onTriggered: {
-                var itemUnder = pArea.childAt(pArea.mouseX, pArea.mouseY)
-                root.headersVisible = pArea.containsMouse && (itemUnder === 
bottomBar || itemUnder === headerBar)
+                if (!root.headersVisible || headerBarArea.containsMouse || 
bottomBarArea.containsMouse) return
+
+                if (renderer.status === "PAUSED" || renderer.status === 
"STOPPED") return
+
+                // Bug?: MouseArea doesn't work over Controls
+                var controls = [ favBtn, chatBtn, playBtn, resetBtn, 
volumeBtn, volumeSlider, seekBar, hwaccelBox, sourcesBox, cropBtn, fsBtn];
+                for (var i = 0; i < controls.length; i++) {
+                    if (controls[i].hovered || controls[i].pressed || 
controls[i].down)
+                        return;
+                }
+
+                root.headersVisible = false
             }
         }
 
@@ -434,6 +553,7 @@
 
             clip: true
             height: root.headersVisible ? 55 : 0
+            visible: height > 0
 
             Behavior on height {
                 NumberAnimation {
@@ -441,6 +561,12 @@
                 }
             }
 
+            MouseArea {
+                id: headerBarArea
+                anchors.fill: parent
+                hoverEnabled: true
+            }
+
             RowLayout {
                 anchors {
                     fill: parent
@@ -508,9 +634,9 @@
                 left: parent.left
                 right: parent.right
             }
-
-            clip: true
+            clip: false
             height: root.headersVisible ? 55 : 0
+            visible: height > 0
 
             Behavior on height {
                 NumberAnimation {
@@ -518,16 +644,85 @@
                 }
             }
 
+            MouseArea {
+                id: bottomBarArea
+                anchors.fill: parent
+                hoverEnabled: true
+            }
+
+            Slider {
+                id: seekBar
+                from: 0
+                to: duration
+                visible: isVod && headersVisible
+                padding: 0
+                hoverEnabled: true
+                clip: true
+
+                anchors {
+                    verticalCenter: parent.top
+                    left: parent.left
+                    right: parent.right
+                }
+
+                Component.onCompleted: {
+                    handle.opacity = 0;
+                }
+
+                PropertyAnimation {
+                    id: handleAnimation
+                    target: seekBar.handle
+                    easing.type: Easing.OutQuad
+                    property: "opacity"
+                    duration: 400
+                    running: false
+                }
+
+                onHoveredChanged: {
+                    var wantedOpacity = hovered || pressed ? 1 : 0;
+                    if (handle.opacity === wantedOpacity) return;
+                    handleAnimation.to = wantedOpacity;
+                    handleAnimation.restart();
+                }
+                onPressedChanged: {
+                    if (!pressed)
+                        seekTo(value)
+                }
+
+                property real prev: 0
+                onValueChanged: {
+                    if (seekTimer.running)
+                        value = seekTimer.to
+                }
+
+                Timer {
+                    id: seekTimer
+                    interval: 500
+                    repeat: false
+                    property real to: 0
+                    onTriggered: {
+                        seekTo(seekBar.value);
+                    }
+                }
+
+                function seek(val) {
+                    seekTimer.to = val
+                    value = val
+                    seekTimer.restart()
+                }
+            }
+
             RowLayout {
                 anchors {
                     fill: parent
                     rightMargin: 5
                     leftMargin: 5
-                }
+                }                
+                spacing: 0
 
                 IconButtonFlat {
                     id: playBtn
-                    text: renderer.status !== "PLAYING" ? "\ue037" : "\ue034"
+                    text: renderer.status !== "PLAYING" && renderer.status !== 
"BUFFERING" ? "\ue037" : "\ue034"
                     onClicked: renderer.togglePause()
                 }
 
@@ -537,39 +732,21 @@
                     onClicked: reloadStream()
                 }
 
-                //spacer
-                Item {
-                    Layout.minimumWidth: 0
-                    Layout.fillWidth: true
-                }
-
-                IconButtonFlat {
-                    id: cropBtn
-                    visible: !appFullScreen && !isMobile() && !chat.visible && 
parent.width > 440
-                    text: "\ue3bc"
-                    onClicked: fitToAspectRatio()
-                }
-
-                IconButtonFlat {
-                    id: fsBtn
-                    visible: !isMobile()
-                    text: !appFullScreen ? "\ue5d0" : "\ue5d1"
-                    onClicked: appFullScreen = !appFullScreen
-                }
-
                 IconButtonFlat {
                     id: volumeBtn
-                    visible: !isMobile() && parent.width > 390
+                    visible: !isMobile()
                     property real mutedValue: 100.0
                     text: volumeSlider.value > 0 ?
                               (volumeSlider.value > 50 ? "\ue050" : "\ue04d")
                             : "\ue04f"
                     onClicked: {
+                        toggleMute()
+                    }
+                    function toggleMute() {
                         if (volumeSlider.value > 0) {
                             mutedValue = volumeSlider.value
                             volumeSlider.value = 0
-                        }
-                        else {
+                        } else {
                             volumeSlider.value = mutedValue
                         }
                     }
@@ -579,19 +756,116 @@
                     id: volumeSlider
                     from: 0
                     to: 100
+                    width: 0
+                    opacity: 0
                     visible: !isMobile()
-                    Layout.maximumWidth: 90
+                    Layout.maximumWidth: width
+                    hoverEnabled: true
+
+                    Behavior on width { PropertyAnimation { easing.type: 
Easing.InOutQuad } }
+                    Behavior on opacity { PropertyAnimation { easing.type: 
Easing.InOutQuad } }
+
                     Component.onCompleted: {
                         value = Settings.volumeLevel
+                        renderer.setVolume(value)
+
+                        playBtn.hoverEnabled = true
+                        resetBtn.hoverEnabled = true
+                        volumeBtn.hoverEnabled = true
+                    }
+
+                    Connections { target: playBtn; onHoveredChanged: 
volumeSlider.update(); onPressedChanged: volumeSlider.update() }
+                    Connections { target: resetBtn; onHoveredChanged: 
volumeSlider.update(); onPressedChanged: volumeSlider.update() }
+                    Connections { target: volumeBtn; onHoveredChanged: 
volumeSlider.update(); onPressedChanged: volumeSlider.update() }
+
+                    // Volume slider behavior similar to youtube
+                    function update() {
+                        if (opacity > 0 && (playBtn.hovered || 
resetBtn.hovered)) {
+                            opacity = 1
+                            width = 90
+                        } else if (hovered || pressed || volumeBtn.hovered || 
volumeBtn.pressed) {
+                            opacity = 1
+                            width = 90
+                        } else {
+                            opacity = 0
+                            width = 0
+                        }
                     }
 
+                    onHoveredChanged: update()
+                    onPressedChanged: update()
+
                     onValueChanged: {
-                        var val = value
-                        if (Qt.platform === "linux" && player_backend === 
"mpv")
-                            val = Math.round(Math.log(val) / Math.log(100))
+                        renderer.setVolume(value)
+                        Settings.volumeLevel = value;
+                    }
+                }
+
+                //spacer
+                Label {
+                    id: videoPositionLabel
+                    Layout.minimumWidth: 0
+                    Layout.fillWidth: true
+                    font.bold: true
+                    font.pointSize: 8
+                    Material.foreground: Material.Grey
+                    horizontalAlignment: Qt.AlignLeft
+                    clip: true
+                    function updateText() {
+                        if (!isVod) return ""
+                        var formatTime = function(seconds) {
+                            var d = new Date()
+                            d.setTime(seconds * 1000)
+                            d.setMinutes(d.getMinutes() + 
d.getTimezoneOffset())
+                            return d.toTimeString()
+                        }
+                        text = formatTime(seekBar.value) + "/" + 
formatTime(duration)
+                    }
+                    Connections {
+                        target: seekBar
+                        onValueChanged: videoPositionLabel.updateText()
+                    }
+                    Connections {
+                        target: renderer
+                        onPlayingStopped: videoPositionLabel.text = ""
+                    }
+                }
+
+
+                ComboBox {
+                    id: hwaccelBox
+                    font.pointSize: 9
+                    font.bold: true
+                    focusPolicy: Qt.NoFocus
+                    flat: true
+                    Layout.fillWidth: true
+                    Layout.maximumWidth: 140
+                    Layout.minimumWidth: 100
+                    visible: renderer.getDecoder().length > 1
 
-                        renderer.setVolume(val)
-                        Settings.volumeLevel = val;
+                    onCurrentIndexChanged: {
+                        renderer.setDecoder(currentIndex)
+                        loadAndPlay()
+                        Settings.decoder = hwaccelBox.model[currentIndex]
+                        pArea.refreshHeaders()
+                    }
+
+                    Component.onCompleted: {
+                        var decoder = renderer.getDecoder()
+                        hwaccelBox.model = decoder
+                        selectItem(Settings.decoder)
+                        renderer.setDecoder(currentIndex)
+                    }
+
+                    function selectItem(name) {
+                        for (var i in hwaccelBox.model) {
+                            if (hwaccelBox.model[i] === name) {
+                                currentIndex = i;
+                                return;
+                            }
+                        }
+                        //None found, attempt to select first item
+                        currentIndex = 0
                     }
                 }
 
@@ -599,13 +873,14 @@
                     id: sourcesBox
                     font.pointSize: 9
                     font.bold: true
+                    focusPolicy: Qt.NoFocus
                     flat: true
                     Layout.fillWidth: true
                     Layout.maximumWidth: 140
                     Layout.minimumWidth: 100
 
-                    onActivated: {
-                        Settings.quality = sourcesBox.model[index]
+                    onCurrentIndexChanged: {
+                        Settings.quality = sourcesBox.model[currentIndex]
                         loadAndPlay()
                         pArea.refreshHeaders()
                     }
@@ -621,23 +896,20 @@
                         currentIndex = 0
                     }
                 }
-            }
-        }
 
-        Slider {
-            id: seekBar
-            from: 0
-            to: duration
-            visible: isVod && headersVisible
-            padding: 0
-            anchors {
-                verticalCenter: bottomBar.top
-                left: parent.left
-                right: parent.right
-            }
-            onPressedChanged: {
-                if (!pressed)
-                    seekTo(value)
+                IconButtonFlat {
+                    id: cropBtn
+                    visible: !appFullScreen && !isMobile() && !chat.visible && 
parent.width > 440
+                    text: "\ue3bc"
+                    onClicked: fitToAspectRatio()
+                }
+
+                IconButtonFlat {
+                    id: fsBtn
+                    visible: !isMobile()
+                    text: !appFullScreen ? "\ue5d0" : "\ue5d1"
+                    onClicked: appFullScreen = !appFullScreen
+                }
             }
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/QtAVBackend.qml 
new/orion-1.6.5+git~20181007/src/qml/QtAVBackend.qml
--- old/orion-1.6.5+git~20180524/src/qml/QtAVBackend.qml        2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/qml/QtAVBackend.qml        2018-10-07 
17:50:22.000000000 +0200
@@ -25,6 +25,8 @@
 stop()              -- Stops playback
 seekTo(pos)         -- Seeks to milliseconds in the current source, works only 
on vods
 setVolume(vol)      -- Number between 0 - 100
+getDecoder()        -- Return list of video decoders
+setDecoder(idx)     -- Set video decoder
 
 Signals needed:
 playingResumed()    -- Signaled when playback toggles from paused / stopped to 
playing
@@ -48,12 +50,13 @@
 
         stop();
 
+        renderer.source = src
+        renderer.startPosition = 0
+
         if (start >= 0) {
             seekTo(start)
         }
 
-        renderer.source = src
-
         resume()
     }
 
@@ -77,6 +80,8 @@
     }
 
     function seekTo(pos) {
+        status = "BUFFERING"
+        renderer.startPosition = pos * 1000
         renderer.seek(pos * 1000)
         root.position = pos
     }
@@ -85,6 +90,40 @@
         volume = Math.round(vol)
     }
 
+    function getDecoder() {
+        var defaultDecoders = renderer.videoCodecs
+        var decoder = [ "auto" ]
+        decoder = decoder.concat(defaultDecoders);
+        return decoder
+    }
+
+    function setDecoder(idx) {
+        var decoderName = getDecoder()[idx]
+
+        var opt = renderer.videoCodecOptions
+        opt["copyMode"] = Qt.platform.os == "android" ? "OptimizedCopy" : 
"ZeroCopy"
+        renderer.videoCodecOptions = opt
+
+        if (decoderName === "auto") {
+            if (g_instance === "child") {
+                // disable automatic hw acceleration for multiple instances 
(usually results in lag)
+                renderer.videoCodecPriority = [ "FFmpeg" ]
+            } else if (Qt.platform.os == "windows") {
+                renderer.videoCodecPriority = [ "DXVA", "FFmpeg" ]
+            } else if (Qt.platform.os == "winrt" || Qt.platform.os == 
"winphone") {
+                renderer.videoCodecPriority = [ "D3D11", "FFmpeg" ]
+            } else if (Qt.platform.os == "osx" || Qt.platform.os == "ios") {
+                renderer.videoCodecPriority = [ "VideoToolbox", "FFmpeg" ]
+            } else if(Qt.platform.os == "android") {
+                renderer.videoCodecPriority = [ "MediaCodec", "FFmpeg" ]
+            } else if (Qt.platform.os == "linux") {
+                renderer.videoCodecPriority = [ "VAAPI", "FFmpeg" ]
+            }
+        } else {
+            renderer.videoCodecPriority = [ decoderName ]
+        }
+    }
+
     signal playingResumed()
     signal playingPaused()
     signal playingStopped()
@@ -119,6 +158,22 @@
     MediaPlayer {
         id: renderer
 
+        function updateStatus() {
+            if (status === MediaPlayer.Buffering) {
+                root.status = "BUFFERING"
+            } else if (playbackState === MediaPlayer.PlayingState) {
+                root.status = "PLAYING"
+            } else if (playbackState === MediaPlayer.PausedState) {
+                root.status = "PAUSED"
+            } else if (playbackState === MediaPlayer.StoppedState) {
+                root.status = "STOPPED"
+            }
+        }
+
+        onStatusChanged: {
+            updateStatus()
+        }
+
         onStopped: {
             root.status = "STOPPED"
             root.playingStopped()
@@ -134,9 +189,14 @@
             root.playingResumed()
         }
 
+        onSeekFinished: {
+            updateStatus()
+        }
+
         onPositionChanged: {
+            if (root.status !== "PLAYING") return
             var pos = position / 1000
-            if (root.position !== pos)
+            if (root.position !== pos && (startPosition === 0 || position > 0))
                 root.position = pos
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/orion-1.6.5+git~20180524/src/qml/components/IconButtonFlat.qml 
new/orion-1.6.5+git~20181007/src/qml/components/IconButtonFlat.qml
--- old/orion-1.6.5+git~20180524/src/qml/components/IconButtonFlat.qml  
2018-05-24 17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/qml/components/IconButtonFlat.qml  
2018-10-07 17:50:22.000000000 +0200
@@ -5,4 +5,5 @@
     font.pointSize: 16
     flat: true
     font.family: "Material Icons"
+    focusPolicy: Qt.NoFocus
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/orion-1.6.5+git~20180524/src/qml/components/OptionCombo.qml 
new/orion-1.6.5+git~20181007/src/qml/components/OptionCombo.qml
--- old/orion-1.6.5+git~20180524/src/qml/components/OptionCombo.qml     
2018-05-24 17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/qml/components/OptionCombo.qml     
2018-10-07 17:50:22.000000000 +0200
@@ -22,6 +22,7 @@
     property alias text: label.text
     property alias selection: combo.currentIndex
     property alias model: combo.model
+    property alias currentIndex: combo.currentIndex
 
     signal activated(int index)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/irc/ChatView.qml 
new/orion-1.6.5+git~20181007/src/qml/irc/ChatView.qml
--- old/orion-1.6.5+git~20180524/src/qml/irc/ChatView.qml       2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/qml/irc/ChatView.qml       2018-10-07 
17:50:22.000000000 +0200
@@ -157,6 +157,7 @@
             id: pinBtn
             checkable: true
             font.family: "Material Icons"
+            focusPolicy: Qt.NoFocus
             text: checked ? "\ue897" : "\ue898"
         }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/orion-1.6.5+git~20180524/src/qml/main.qml 
new/orion-1.6.5+git~20181007/src/qml/main.qml
--- old/orion-1.6.5+git~20180524/src/qml/main.qml       2018-05-24 
17:25:25.000000000 +0200
+++ new/orion-1.6.5+git~20181007/src/qml/main.qml       2018-10-07 
17:50:22.000000000 +0200
@@ -47,7 +47,7 @@
                                   || Screen.primaryOrientation === 
Qt.InvertedPortraitOrientation
 
     function fitToAspectRatio() {
-        height = Math.floor(view.width * 0.5625 + topbar.height)
+        height = Math.floor(view.width * 0.5625)
     }
 
     function isMobile() {


Reply via email to