]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/panels/terminal/terminalpanel.cpp
Merge branch 'release/20.04'
[dolphin.git] / src / panels / terminal / terminalpanel.cpp
index 8dedd0be11adb4baa2cbceedbad7d46be4644100..ac0bcd0fee5c1ef9fadd3ed0b2946da9dc4b3565 100644 (file)
@@ -18,6 +18,7 @@
  ***************************************************************************/
 
 #include "terminalpanel.h"
+#include "kiofuse_interface.h"
 
 #include <KIO/DesktopExecParser>
 #include <KIO/Job>
@@ -25,6 +26,7 @@
 #include <KJobWidgets>
 #include <KLocalizedString>
 #include <KMessageWidget>
+#include <KMountPoint>
 #include <KParts/ReadOnlyPart>
 #include <KPluginFactory>
 #include <KPluginLoader>
@@ -50,7 +52,10 @@ TerminalPanel::TerminalPanel(QWidget* parent) :
     m_konsolePartMissingMessage(nullptr),
     m_konsolePart(nullptr),
     m_konsolePartCurrentDirectory(),
-    m_sendCdToTerminalHistory()
+    m_sendCdToTerminalHistory(),
+    m_kiofuseInterface(QStringLiteral("org.kde.KIOFuse"),
+                       QStringLiteral("/org/kde/KIOFuse"),
+                       QDBusConnection::sessionBus())
 {
     m_layout = new QVBoxLayout(this);
     m_layout->setContentsMargins(0, 0, 0, 0);
@@ -82,16 +87,14 @@ void TerminalPanel::terminalExited()
 bool TerminalPanel::isHiddenInVisibleWindow() const
 {
     return parentWidget()
-        && parentWidget()->isHidden()
-        && m_terminal
-        && !hasProgramRunning();
+        && parentWidget()->isHidden();
 }
 
 void TerminalPanel::dockVisibilityChanged()
 {
     // Only react when the DockWidget itself (not some parent) is hidden. This way we don't
     // respond when e.g. Dolphin is minimized.
-    if (isHiddenInVisibleWindow()) {
+    if (isHiddenInVisibleWindow() && m_terminal && !hasProgramRunning()) {
         // Make sure that the following "cd /" command will not affect the view.
         disconnect(m_konsolePart, SIGNAL(currentDirectoryChanged(QString)),
                    this, SLOT(slotKonsolePartCurrentDirectoryChanged(QString)));
@@ -149,6 +152,7 @@ void TerminalPanel::showEvent(QShowEvent* event)
         if (m_konsolePart) {
             connect(m_konsolePart, &KParts::ReadOnlyPart::destroyed, this, &TerminalPanel::terminalExited);
             m_terminalWidget = m_konsolePart->widget();
+            setFocusProxy(m_terminalWidget);
             m_layout->addWidget(m_terminalWidget);
             if (m_konsolePartMissingMessage) {
                 m_layout->removeWidget(m_konsolePartMissingMessage);
@@ -177,7 +181,9 @@ void TerminalPanel::showEvent(QShowEvent* event)
     }
     if (m_terminal) {
         m_terminal->showShellInDir(url().toLocalFile());
-        changeDir(url());
+        if(!hasProgramRunning()) {
+            changeDir(url());
+        }
         m_terminalWidget->setFocus();
         connect(m_konsolePart, SIGNAL(currentDirectoryChanged(QString)),
                 this, SLOT(slotKonsolePartCurrentDirectoryChanged(QString)));
@@ -243,6 +249,19 @@ void TerminalPanel::slotMostLocalUrlResult(KJob* job)
     const QUrl url = statJob->mostLocalUrl();
     if (url.isLocalFile()) {
         sendCdToTerminal(url.toLocalFile());
+    } else {
+        // URL isn't local, only hope for the terminal to be in sync with the
+        // DolphinView is to mount the remote URL in KIOFuse and point to it.
+        // If we can't do that for any reason, silently fail.
+        auto reply = m_kiofuseInterface.mountUrl(url.toString());
+        QDBusPendingCallWatcher * watcher = new QDBusPendingCallWatcher(reply, this);
+        QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher* watcher) {
+            watcher->deleteLater();
+            if (!reply.isError()) {
+                // Successfully mounted, point to the KIOFuse equivalent path.
+                sendCdToTerminal(reply.value());
+            }
+        });
     }
 
     m_mostLocalUrlJob = nullptr;
@@ -260,6 +279,38 @@ void TerminalPanel::slotKonsolePartCurrentDirectoryChanged(const QString& dir)
         }
     }
 
+    // User may potentially be browsing inside a KIOFuse mount.
+    // If so lets try and change the DolphinView to point to the remote URL equivalent.
+    // instead of into the KIOFuse mount itself (which can cause performance issues!)
     const QUrl url(QUrl::fromLocalFile(dir));
-    emit changeUrl(url);
+
+    KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByPath(m_konsolePartCurrentDirectory);
+    if (mountPoint && mountPoint->mountType() != QStringLiteral("fuse.kio-fuse")) {
+        // Not in KIOFUse mount, so just switch to the corresponding URL.
+        emit changeUrl(url);
+        return;
+    }
+
+    auto reply = m_kiofuseInterface.remoteUrl(m_konsolePartCurrentDirectory);
+    QDBusPendingCallWatcher * watcher = new QDBusPendingCallWatcher(reply, this);
+    QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher* watcher) {
+        watcher->deleteLater();
+        if (reply.isError()) {
+            // KIOFuse errored out... just show the normal URL
+            emit changeUrl(url);
+        } else {
+            // Our location happens to be in a KIOFuse mount and is mounted.
+            // Let's change the DolphinView to point to the remote URL equivalent.
+            emit changeUrl(QUrl::fromUserInput(reply.value()));
+        }
+    });
+}
+
+bool TerminalPanel::terminalHasFocus() const
+{
+    if (m_terminalWidget) {
+        return m_terminalWidget->hasFocus();
+    }
+
+    return hasFocus();
 }