Kaynağa Gözat

KonvergoWindow: fix QML change notifications

The old code probably didn't miss any change notifications, but it sent
too many of them. QML won't figure out property changes on its own, and
might recompute property bindings on every change notification. I
suspect this caused "binding loops" and crashes. (I wasn't able to
reproduce them. There is no doubt binding loops happen, and they are
most likely responsible for crashes we are seeing.)

Make change notifications fine-grained for every relevant property. Most
of these are for the web scaling nightmare, and thus are size-dependent.
Some also depend on the web mode (TV vs. desktop), but the commit moves
this dependency into the .qml, which makes this much easier.

The webUrl property remains a bit "dangerous", because the initialScale
parameter takes a snapshot value. Re-reading the webUrl property might
return a different value at runtime, but we do _not_ want to have a
proper change notification, as that would make the WebEngine element
reload the URL. We don't want to reload web-client only because it's
resized. I'm hoping to get rid of the initialScale URL parameter
completely. Currently it's definitely needed.
Vincent Lang 7 yıl önce
ebeveyn
işleme
a655e7735e
3 değiştirilmiş dosya ile 72 ekleme ve 51 silme
  1. 56 34
      src/ui/KonvergoWindow.cpp
  2. 14 15
      src/ui/KonvergoWindow.h
  3. 2 2
      src/ui/webview.qml

+ 56 - 34
src/ui/KonvergoWindow.cpp

@@ -25,7 +25,7 @@
 KonvergoWindow::KonvergoWindow(QWindow* parent) :
   QQuickWindow(parent),
   m_debugLayer(false),
-  m_lastWindowScale(-1), m_lastWebScale(-1),
+  m_lastWindowScale(-1), m_lastWebScale(-1), m_tvUIw(-1), m_tvUIh(-1),
   m_ignoreFullscreenSettingsChange(0),
   m_showedUpdateDialog(false),
   m_osxPresentationOptions(0)
@@ -58,8 +58,7 @@ KonvergoWindow::KonvergoWindow(QWindow* parent) :
 #endif
 
   QRect loadedGeo = loadGeometry();
-  notifyScale(loadedGeo.size());
-  emit webScaleChanged();
+  updateSizeDependendProperties(loadedGeo.size());
 
   connect(SettingsComponent::Get().getSection(SETTINGS_SECTION_MAIN), &SettingsSection::valuesUpdated,
           this, &KonvergoWindow::updateMainSectionSettings);
@@ -363,37 +362,44 @@ void KonvergoWindow::updateMainSectionSettings(const QVariantMap& values)
 
     if (SettingsComponent::Get().value(SETTINGS_SECTION_MAIN, "layout").toString() != "auto")
     {
-      m_webDesktopMode = newDesktopMode;
-      emit webDesktopModeChanged();
-      emit webUrlChanged();
-      emit webScaleChanged();
+      if (oldDesktopMode != newDesktopMode)
+      {
+        PlayerComponent::Get().stop();
+        m_webDesktopMode = newDesktopMode;
+        emit webDesktopModeChanged();
+        emit webUrlChanged();
+      }
     }
     else
     {
-      bool fullscreen = SettingsComponent::Get().value(SETTINGS_SECTION_MAIN, "fullscreen").toBool();
+      bool oldFullscreen = SettingsComponent::Get().value(SETTINGS_SECTION_MAIN, "fullscreen").toBool();
+      bool newFullscreen = oldFullscreen;
 
       if (oldDesktopMode && !newDesktopMode)
-        fullscreen = true;
+        newFullscreen = true;
       else if (!oldDesktopMode && newDesktopMode)
-        fullscreen = false;
+        newFullscreen = false;
 
-      PlayerComponent::Get().stop();
+      if (oldFullscreen != newFullscreen)
+        SettingsComponent::Get().setValue(SETTINGS_SECTION_MAIN, "fullscreen", newFullscreen);
 
-      SettingsComponent::Get().setValue(SETTINGS_SECTION_MAIN, "fullscreen", fullscreen);
-      QTimer::singleShot(0, [=]
+      if (oldDesktopMode != newDesktopMode)
       {
-        m_webDesktopMode = newDesktopMode;
-        auto s = size();
-        QLOG_DEBUG() << "compute scale for mode switch" << s;
-        notifyScale(s);
-        emit webDesktopModeChanged();
-        emit webUrlChanged();
-        emit webScaleChanged();
-
-        if (m_webDesktopMode)
-          SystemComponent::Get().setCursorVisibility(true);
-        updateWindowState();
-      });
+        QTimer::singleShot(0, [=]
+        {
+          PlayerComponent::Get().stop();
+          m_webDesktopMode = newDesktopMode;
+          auto s = size();
+          QLOG_DEBUG() << "compute scale for mode switch" << s;
+          updateSizeDependendProperties(s);
+          emit webDesktopModeChanged();
+          emit webUrlChanged();
+
+          if (m_webDesktopMode)
+            SystemComponent::Get().setCursorVisibility(true);
+          updateWindowState();
+        });
+      }
     }
   }
 
@@ -546,8 +552,7 @@ void KonvergoWindow::onVisibilityChanged(QWindow::Visibility visibility)
 #endif
 
   InputComponent::Get().cancelAutoRepeat();
-  notifyScale(size());
-  emit webScaleChanged();
+  updateSizeDependendProperties(size());
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -625,17 +630,35 @@ void KonvergoWindow::toggleDebug()
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
-void KonvergoWindow::notifyScale(const QSize& size)
+void KonvergoWindow::updateSizeDependendProperties(const QSize& size)
 {
   qreal windowScale = CalculateScale(size);
-  qreal webScale = CalculateWebScale(size, devicePixelRatio());
-  if (windowScale != m_lastWindowScale || webScale != m_lastWebScale)
+  if (windowScale != m_lastWindowScale)
   {
-    QLOG_DEBUG() << "windowScale updated to:" << windowScale << "webscale:" << webScale;
-
     m_lastWindowScale = windowScale;
+    emit windowScaleChanged();
+  }
+
+  qreal webScale = CalculateWebScale(size, devicePixelRatio());
+  if (webScale != m_lastWebScale)
+  {
     m_lastWebScale = webScale;
     emit SystemComponent::Get().updateScale(webScale);
+    emit webScaleChanged();
+  }
+
+  qreal tvW = qRound64(qMin((qreal)(size.height() * 16) / 9, (qreal)size.width()));
+  if (tvW != m_tvUIw)
+  {
+    m_tvUIw = tvW;
+    emit tvUIWidthChanged();
+  }
+
+  qreal tvH = qRound64(qMin((qreal)(size.width() * 9) / 16, (qreal)size.height()));
+  if (tvH != m_tvUIh)
+  {
+    m_tvUIh = tvH;
+    emit tvUIHeightChanged();
   }
 }
 
@@ -668,8 +691,7 @@ void KonvergoWindow::resizeEvent(QResizeEvent* event)
   }
   #endif
 
-  notifyScale(event->size());
-  emit webScaleChanged();
+  updateSizeDependendProperties(event->size());
   QQuickWindow::resizeEvent(event);
 }
 

+ 14 - 15
src/ui/KonvergoWindow.h

@@ -30,14 +30,14 @@ class KonvergoWindow : public QQuickWindow
   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(qreal windowScale READ windowScale NOTIFY webScaleChanged)
-  Q_PROPERTY(QSize windowMinSize READ windowMinSize NOTIFY webScaleChanged)
+  Q_PROPERTY(qreal webHeightMax READ webHeightMax)
+  Q_PROPERTY(qreal windowScale READ windowScale NOTIFY windowScaleChanged)
+  Q_PROPERTY(QSize windowMinSize READ windowMinSize)
   Q_PROPERTY(bool alwaysOnTop READ isAlwaysOnTop WRITE setAlwaysOnTop)
   Q_PROPERTY(bool webDesktopMode MEMBER m_webDesktopMode NOTIFY webDesktopModeChanged)
   Q_PROPERTY(QString webUrl READ webUrl NOTIFY webUrlChanged)
-  Q_PROPERTY(qreal webUIWidth READ webUIWidth NOTIFY webScaleChanged)
-  Q_PROPERTY(qreal webUIHeight READ webUIHeight NOTIFY webScaleChanged)
+  Q_PROPERTY(qreal tvUIWidth READ tvUIWidth NOTIFY tvUIWidthChanged)
+  Q_PROPERTY(qreal tvUIHeight READ tvUIHeight NOTIFY tvUIHeightChanged)
 
 public:
   static void RegisterClass();
@@ -97,29 +97,28 @@ public:
   QSize windowMinSize() { return WINDOWW_MIN_SIZE; }
   QString webUrl();
 
-  qreal webUIWidth()
+  qreal tvUIWidth()
   {
-    if (!m_webDesktopMode)
-      return qRound64(qMin((qreal)(height() * 16) / 9, (qreal)width()));
-    return width();
+    return m_tvUIw;
   }
 
-  qreal webUIHeight()
+  qreal tvUIHeight()
   {
-    if (!m_webDesktopMode)
-      return qRound64(qMin((qreal)(width() * 9) / 16, (qreal)height()));
-    return height();
+    return m_tvUIh;
   }
 
 Q_SIGNALS:
   void fullScreenSwitched();
   void webScaleChanged();
+  void windowScaleChanged();
   void enableVideoWindowSignal();
   void debugLayerChanged();
   void debugInfoChanged();
   void reloadWebClient();
   void webDesktopModeChanged();
   void webUrlChanged();
+  void tvUIWidthChanged();
+  void tvUIHeightChanged();
 
 protected:
   void focusOutEvent(QFocusEvent* ev) override;
@@ -139,7 +138,7 @@ private slots:
   void updateCurrentScreen();
 
 private:
-  void notifyScale(const QSize& size);
+  void updateSizeDependendProperties(const QSize& size);
   void saveGeometry();
   QRect loadGeometry();
   QRect loadGeometryRect();
@@ -150,7 +149,7 @@ private:
   QScreen* findCurrentScreen();
 
   bool m_debugLayer;
-  qreal m_lastWindowScale, m_lastWebScale;
+  qreal m_lastWindowScale, m_lastWebScale, m_tvUIw, m_tvUIh;
   QTimer* m_infoTimer;
   QString m_debugInfo, m_systemDebugInfo, m_videoInfo;
   int m_ignoreFullscreenSettingsChange;

+ 2 - 2
src/ui/webview.qml

@@ -153,8 +153,8 @@ KonvergoWindow
     focus: true
     property string currentHoveredUrl: ""
     onLinkHovered: web.currentHoveredUrl = hoveredUrl
-    width: mainWindow.webUIWidth
-    height: mainWindow.webUIHeight
+    width: mainWindow.webDesktopMode ? mainWindow.width : mainWindow.tvUIWidth
+    height: mainWindow.webDesktopMode ? mainWindow.height : mainWindow.tvUIHeight
 
     scale:
     {