Jelajahi Sumber

Add "Always on top" option as a setting

- Allow the Plex Media Player window to flow above any other windows
- Expose a "alwaysOnTop" control in the settings panel
- Allow the always-on-top state to be toggled using the shortcut CMD|Ctrl+Shift+A or T

Plex-CLA-1.0-signed-off-by: Lukas Pitschl <lukas@leftandleaving.com>
Lukas Pitschl 8 tahun lalu
induk
melakukan
0f6b06da36

+ 2 - 0
resources/inputmaps/keyboard.json

@@ -52,12 +52,14 @@
     "Ctrl\\+Q": "host:close",
     "Ctrl\\+Shift\\+R": "host:reload",
     "Ctrl\\+Shift\\+D": "host:toggleDebug",
+    "Ctrl\\+Shift\\+A": "host:alwaysOnTop",
 
     // emulate some of of PHT's behaviour
     "I": "host:toggleDebug",
     "W": "toggle_watched",
     "\\\\": "host:fullscreen",
     "Z": "host:cycle_setting video.aspect",
+    "T": "host:alwaysOnTop",
 
     // media keys from the FLIRC and on Linux keyboards
     "Toggle Media Play\\/Pause": "play_pause",

+ 4 - 0
resources/settings/settings_description.json

@@ -34,6 +34,10 @@
         "platforms": [ "windows" ],
         "hidden": true
       },
+      {
+        "value": "alwaysOnTop",
+        "default": false
+      },
       {
         "value": "webserverport",
         "default": 32433,

+ 39 - 0
src/ui/KonvergoWindow.cpp

@@ -35,6 +35,7 @@ KonvergoWindow::KonvergoWindow(QWindow* parent) : QQuickWindow(parent), m_debugL
   InputComponent::Get().registerHostCommand("toggleDebug", this, "toggleDebug");
   InputComponent::Get().registerHostCommand("reload", this, "reloadWeb");
   InputComponent::Get().registerHostCommand("fullscreen", this, "toggleFullscreen");
+  InputComponent::Get().registerHostCommand("alwaysOnTop", this, "toggleAlwaysOnTop");
 
 #ifdef TARGET_RPI
   // On RPI, we use dispmanx layering - the video is on a layer below Konvergo,
@@ -71,6 +72,9 @@ KonvergoWindow::KonvergoWindow(QWindow* parent) : QQuickWindow(parent), m_debugL
   updateFullscreenState(false);
 #endif
 
+  // Check the always on top setting and activate it if necessary.
+  updateAlwaysOnTopState();
+
   emit enableVideoWindowSignal();
 }
 
@@ -209,6 +213,15 @@ void KonvergoWindow::setFullScreen(bool enable)
   SettingsComponent::Get().setValue(SETTINGS_SECTION_MAIN, "fullscreen", enable);
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void KonvergoWindow::setAlwaysOnTop(bool enable)
+{
+  QLOG_DEBUG() << "setting always on top = " << enable;
+
+  // Update the settings value.
+  SettingsComponent::Get().setValue(SETTINGS_SECTION_MAIN, "alwaysOnTop", enable);
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 void KonvergoWindow::playerWindowVisible(bool visible)
 {
@@ -227,6 +240,11 @@ void KonvergoWindow::updateMainSectionSettings(const QVariantMap& values)
     SystemComponent::Get().setCursorVisibility(!SettingsComponent::Get().value(SETTINGS_SECTION_MAIN, "disablemouse").toBool());
   }
 
+  if (values.find("alwaysOnTop") != values.end())
+  {
+    updateAlwaysOnTopState();
+  }
+
   if (values.find("fullscreen") == values.end())
     return;
 
@@ -252,6 +270,27 @@ void KonvergoWindow::updateFullscreenState(bool saveGeo)
   }
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void KonvergoWindow::updateAlwaysOnTopState()
+{
+  QLOG_DEBUG() << "Changing always-on-top state";
+  Qt::WindowFlags forceOnTopFlags = Qt::WindowStaysOnTopHint;
+#ifdef Q_OS_LINUX
+  forceOnTopFlags = forceOnTopFlags | Qt::X11BypassWindowManagerHint;
+#endif
+
+  if(SettingsComponent::Get().value(SETTINGS_SECTION_MAIN, "alwaysOnTop").toBool())
+  {
+    setFlags(flags() | forceOnTopFlags);
+  }
+  else
+  {
+    setFlags(flags() & ~forceOnTopFlags);
+  }
+
+  show();
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 void KonvergoWindow::onVisibilityChanged(QWindow::Visibility visibility)
 {

+ 18 - 0
src/ui/KonvergoWindow.h

@@ -33,6 +33,7 @@ class KonvergoWindow : public QQuickWindow
   Q_PROPERTY(QSize webUISize READ webUISize NOTIFY webScaleChanged)
   Q_PROPERTY(qreal windowScale READ windowScale NOTIFY webScaleChanged)
   Q_PROPERTY(QSize windowMinSize READ windowMinSize NOTIFY webScaleChanged)
+  Q_PROPERTY(bool alwaysOnTop READ isAlwaysOnTop WRITE setAlwaysOnTop)
 
 public:
   static void RegisterClass();
@@ -47,6 +48,17 @@ public:
 
   void setFullScreen(bool enable);
 
+  bool isAlwaysOnTop()
+  {
+    Qt::WindowFlags forceOnTopFlags = Qt::WindowStaysOnTopHint;
+#ifdef Q_OS_LINUX
+    forceOnTopFlags = forceOnTopFlags | Qt::X11BypassWindowManagerHint;
+#endif
+    return (flags() & forceOnTopFlags);
+  }
+
+  void setAlwaysOnTop(bool enable);
+
   Q_SLOT void otherAppFocus()
   {
     setWindowState((Qt::WindowState)((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive));
@@ -60,6 +72,11 @@ public:
     setFullScreen(!isFullScreen());
   }
 
+  Q_SLOT void toggleAlwaysOnTop()
+  {
+    setAlwaysOnTop(!isAlwaysOnTop());
+  }
+
   Q_SLOT void reloadWeb()
   {
     emit reloadWebClient();
@@ -91,6 +108,7 @@ private slots:
   void onVisibilityChanged(QWindow::Visibility visibility);
   void updateMainSectionSettings(const QVariantMap& values);
   void updateFullscreenState(bool saveGeo = true);
+  void updateAlwaysOnTopState();
   void onScreenCountChanged(int newCount);
   void updateDebugInfo();
   void playerWindowVisible(bool visible);