Ver Fonte

Let the host calculate the scale for the web-client

This introduces two new pieces of information to the web-client. First
the web client is loaded with initialScale=XX on the query string.
Secondly there is now a system component signal that can be used to see
when the scale should be updated: channel.system.onScaleChanged(XX)

We need to make sure that the maxHeight is calculate by splitting it by
devicePixelRatio since size() in Qt is the *real* size and not the size
/ dpr, so when calculating the different scales, make sure to use dpr
to split max height and get a scaled value.

Also trigger the scale update when switching into fullscreen and back
to windowed mode.
Tobias Hieta há 9 anos atrás
pai
commit
fdd3188ad1

+ 1 - 1
resources/settings/settings_description.json

@@ -88,7 +88,7 @@
       {
         "value": "clientUUID",
         "default": "",
-        "hidden": false
+        "hidden": true
       }
     ]
   },

+ 0 - 12
src/main.cpp

@@ -185,18 +185,6 @@ int main(int argc, char *argv[])
     KonvergoWindow::RegisterClass();
     engine->rootContext()->setContextProperty("components", &ComponentManager::Get().getQmlPropertyMap());
 
-    // This controls how big the web view will zoom using semantic zoom
-    // over a specific number of pixels and we run out of space for on screen
-    // tiles in chromium. This only happens on OSX since on other platforms
-    // we can use the GPU to transfer tiles directly but we set the limit on all platforms
-    // to keep it consistent.
-    //
-    // See more discussion in: https://github.com/plexinc/plex-media-player/issues/10
-    // The number of pixels here are REAL pixels, the code in webview.qml will compensate
-    // for a higher DevicePixelRatio
-    //
-    engine->rootContext()->setContextProperty("webMaxHeight", 1440);
-
     // the only way to detect if QML parsing fails is to hook to this signal and then see
     // if we get a valid object passed to it. Any error messages will be reported on stderr
     // but since no normal user should ever see this it should be fine

+ 1 - 0
src/system/SystemComponent.h

@@ -73,6 +73,7 @@ public:
 
 signals:
   void hostMessage(const QString& message);
+  void scaleChanged(qreal scale);
 
 private:
   SystemComponent(QObject* parent = 0);

+ 49 - 1
src/ui/KonvergoWindow.cpp

@@ -19,7 +19,7 @@
 #include "EventFilter.h"
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-KonvergoWindow::KonvergoWindow(QWindow* parent) : QQuickWindow(parent), m_debugLayer(false)
+KonvergoWindow::KonvergoWindow(QWindow* parent) : QQuickWindow(parent), m_debugLayer(false), m_lastScale(1.0)
 {
   // NSWindowCollectionBehaviorFullScreenPrimary is only set on OSX if Qt::WindowFullscreenButtonHint is set on the window.
   setFlags(flags() | Qt::WindowFullscreenButtonHint);
@@ -46,6 +46,7 @@ KonvergoWindow::KonvergoWindow(QWindow* parent) : QQuickWindow(parent), m_debugL
 #endif
 
   loadGeometry();
+  m_lastScale = CalculateScale(size());
 
   connect(SettingsComponent::Get().getSection(SETTINGS_SECTION_MAIN), &SettingsSection::valuesUpdated,
           this, &KonvergoWindow::updateMainSectionSettings);
@@ -207,6 +208,8 @@ void KonvergoWindow::updateFullscreenState()
     setVisibility(QWindow::Windowed);
     loadGeometry();
   }
+  
+  
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -221,6 +224,8 @@ void KonvergoWindow::onVisibilityChanged(QWindow::Visibility visibility)
     PowerComponent::Get().setFullscreenState(true);
   else if (visibility == QWindow::Windowed)
     PowerComponent::Get().setFullscreenState(false);
+
+  notifyScale(size());
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -293,3 +298,46 @@ void KonvergoWindow::toggleDebug()
     setProperty("showDebugLayer", true);
   }
 }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void KonvergoWindow::notifyScale(const QSize& size)
+{
+  qreal scale = CalculateScale(size);
+  if (scale != m_lastScale)
+  {
+    QLOG_DEBUG() << "windowScale updated to:" << scale;
+    m_lastScale = scale;
+
+    emit SystemComponent::Get().scaleChanged(CalculateWebScale(size, devicePixelRatio()));
+  }
+  emit webScaleChanged();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
+void KonvergoWindow::resizeEvent(QResizeEvent* event)
+{
+  notifyScale(event->size());
+  QQuickWindow::resizeEvent(event);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+#define ROUND(x) (qRound(x * 1000) / 1000.0)
+
+/////////////////////////////////////////////////////////////////////////////////////////
+qreal KonvergoWindow::CalculateScale(const QSize& size)
+{
+  qreal horizontalScale = (qreal)size.width() / (qreal)WEBUI_SIZE.width();
+  qreal verticalScale = (qreal)size.height() / (qreal)WEBUI_SIZE.height();
+  return ROUND(qMin(horizontalScale, verticalScale));
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+qreal KonvergoWindow::CalculateWebScale(const QSize& size, qint32 devicePixelRatio)
+{
+  qreal horizontalScale = (qreal)size.width() / (qreal)WEBUI_SIZE.width();
+  qreal verticalScale = (qreal)size.height() / (qreal)WEBUI_SIZE.height();
+
+  qreal minScale = qMin(horizontalScale, qMin(verticalScale, (qreal)(WEBUI_MAX_HEIGHT / devicePixelRatio) / (qreal)WEBUI_SIZE.height()));
+  return ROUND(qMax(1.0, minScale));
+}

+ 32 - 3
src/ui/KonvergoWindow.h

@@ -4,14 +4,34 @@
 #include <QQuickWindow>
 #include <QEvent>
 
+
+// This controls how big the web view will zoom using semantic zoom
+// over a specific number of pixels and we run out of space for on screen
+// tiles in chromium. This only happens on OSX since on other platforms
+// we can use the GPU to transfer tiles directly but we set the limit on all platforms
+// to keep it consistent.
+//
+// See more discussion in: https://github.com/plexinc/plex-media-player/issues/10
+// The number of pixels here are REAL pixels, the code in webview.qml will compensate
+// for a higher DevicePixelRatio
+//
+#define WEBUI_MAX_HEIGHT 1440.0
+#define WEBUI_SIZE QSize(1280, 720)
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 class KonvergoWindow : public QQuickWindow
 {
   Q_OBJECT
+
   Q_PROPERTY(bool fullScreen READ isFullScreen WRITE setFullScreen NOTIFY fullScreenSwitched)
   Q_PROPERTY(bool showDebugLayer MEMBER m_debugLayer NOTIFY debugLayerChanged)
   Q_PROPERTY(QString debugInfo MEMBER m_debugInfo NOTIFY debugInfoChanged)
   Q_PROPERTY(QString videoInfo MEMBER m_videoInfo NOTIFY debugInfoChanged)
+  Q_PROPERTY(qreal webScale READ webScale NOTIFY webScaleChanged)
+  Q_PROPERTY(qreal webHeightMax READ webHeightMax NOTIFY webScaleChanged)
+  Q_PROPERTY(QSize webUISize READ webUISize NOTIFY webScaleChanged)
+  Q_PROPERTY(qreal windowScale READ windowScale NOTIFY webScaleChanged)
+
 public:
   static void RegisterClass();
 
@@ -43,15 +63,24 @@ public:
     emit reloadWebClient();
   }
 
+  qreal windowScale() { return CalculateScale(size()); }
+  qreal webScale() { return CalculateWebScale(size(), devicePixelRatio()); }
+  qreal webHeightMax() { return WEBUI_MAX_HEIGHT; }
+  QSize webUISize() { return WEBUI_SIZE; }
+  static qreal CalculateScale(const QSize& size);
+  static qreal CalculateWebScale(const QSize& size, qint32 devicePixelRatio);
+
 Q_SIGNALS:
   void fullScreenSwitched();
+  void webScaleChanged();
   void enableVideoWindowSignal();
   void debugLayerChanged();
   void debugInfoChanged();
   void reloadWebClient();
 
 protected:
-  virtual void focusOutEvent(QFocusEvent * ev);
+  virtual void focusOutEvent(QFocusEvent* ev) override;
+  virtual void resizeEvent(QResizeEvent* event) override;
 
 private slots:
   void closingWindow();
@@ -65,12 +94,12 @@ private slots:
   void playerPlaybackStarting();
 
 private:
+  void notifyScale(const QSize& size);
   void saveGeometry();
   void loadGeometry();
   QRect loadGeometryRect();
-
-private:
   bool m_debugLayer;
+  qreal m_lastScale;
   QTimer* m_infoTimer;
   QString m_debugInfo, m_systemDebugInfo, m_videoInfo;
 };

+ 26 - 31
src/ui/webview.qml

@@ -9,17 +9,28 @@ KonvergoWindow
   id: mainWindow
   title: "Plex Media Player"
   objectName: "mainWindow"
-  visible: true
   minimumHeight: 240
   minimumWidth: 426
   height: 720
   width: 1280
 
-  function getMaxHeightArg()
+  function getInitialScaleArg()
   {
-    if (webMaxHeight > 0)
-      return "?maxHeight=" + (webMaxHeight / Screen.devicePixelRatio);
-    return ""
+    return "?initialScale=" + webScale
+  }
+
+  function maxWebScale()
+  {
+    return webHeightMax ? ((webHeightMax / Screen.devicePixelRatio) / 720) : 10;
+  }
+
+  onWebScaleChanged:
+  {
+    if (web.url == "")
+    {
+      console.log("Loading web page")
+      web.url = components.settings.value("path", "startupurl") + getInitialScaleArg();
+    }
   }
 
   MpvVideo
@@ -44,37 +55,24 @@ KonvergoWindow
 
     width: Math.min((parent.height * 16) / 9, parent.width)
     height: Math.min((parent.width * 9) / 16, parent.height)
-
-    function getDesiredScale()
-    {
-      var verticalScale = height / 720;
-      var horizontalScale = width / 1280;
-
-      return Math.min(verticalScale, horizontalScale);
-    }
-
+    
     scale:
     {
-      var desiredScale = getDesiredScale();
-      var maximumScale = webMaxHeight ? ((webMaxHeight / Screen.devicePixelRatio) / 720) : 10;
-
-      if (desiredScale < maximumScale) {
+      if (mainWindow.windowScale < mainWindow.maxWebScale()) {
         // Web renders at windows scale, no scaling
         return 1;
       } else {
         // Web should max out at maximum scaling
-        return desiredScale / maximumScale;
+        return mainWindow.windowScale / mainWindow.maxWebScale();
       }
     }
 
     zoomFactor:
     {
-      var desiredScale = getDesiredScale();
-
-      if (desiredScale < 1)
-        return desiredScale;
+      if (mainWindow.windowScale < 1)
+        return mainWindow.windowScale
       else
-       return 1;
+        return 1;
     }
 
     Component.onCompleted:
@@ -84,8 +82,6 @@ KonvergoWindow
       backgroundColor : "#111111"
       forceActiveFocus()
       mainWindow.reloadWebClient.connect(reload)
-
-      url = components.settings.value("path", "startupurl") + getMaxHeightArg()
     }
 
     onLoadingChanged:
@@ -177,10 +173,9 @@ KonvergoWindow
         var dbg = mainWindow.debugInfo + "Window and web\n";
         dbg += "  Window size: " + parent.width + "x" + parent.height + "\n";
         dbg += "  DevicePixel ratio: " + Screen.devicePixelRatio + "\n";
-        dbg += "  Web Max Height: " + (webMaxHeight / Screen.devicePixelRatio) + "\n";
-        dbg += "  Web scale: " + Math.round(web.scale * 100) / 100 + "\n";
-        dbg += "  Desired Scale: " + Math.round(web.getDesiredScale() * 100) / 100 + "\n";
-        dbg += "  Zoom Factor: " + Math.round(web.zoomFactor * 100) / 100 + "\n";
+        dbg += "  Web Max Height: " + (webHeightMax / Screen.devicePixelRatio) + " / Max scale: " + mainWindow.maxWebScale() + "\n";
+        dbg += "  Web scale: " + webScale + " / Window scale: " + windowScale + "\n";
+        dbg += "  Scale applied: " + web.scale + " / Zoom: " + web.zoomFactor + "\n";
 
         return dbg;
       }
@@ -208,4 +203,4 @@ KonvergoWindow
   }
 
   property QtObject webChannel: web.webChannel
-}
+}