[X2Go-Commits] [x2goclient] 02/02: onmainwindow.{cpp, h}: don't use a hardcoded path to xmodmap on OS X and handle errors more gracefully. Fixes: #487.

git-admin at x2go.org git-admin at x2go.org
Wed Jan 13 06:04:12 CET 2016


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository x2goclient.

commit f399a0453487ac97eb113923f7503fd0f06e046d
Author: Mihai Moldovan <ionic at ionic.de>
Date:   Wed Jan 13 06:03:55 2016 +0100

    onmainwindow.{cpp,h}: don't use a hardcoded path to xmodmap on OS X and handle errors more gracefully. Fixes: #487.
---
 debian/changelog     |    2 +
 src/onmainwindow.cpp |  169 +++++++++++++++++++++++++++++++++++++++++---------
 src/onmainwindow.h   |    1 +
 3 files changed, 141 insertions(+), 31 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 5c5bef8..92a3d0e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -14,6 +14,8 @@ x2goclient (4.0.5.1-0x2go1) UNRELEASED; urgency=low
     - x2gosettings.cpp: let centralSettings () return false on Windows.
     - onmainwindow.cpp: be more precise in slotScDaemonError () regarding
       unknown and undefined errors.
+    - onmainwindow.{cpp,h}: don't use a hardcoded path to xmodmap on OS X and
+      handle errors more gracefully. Fixes: #487.
 
   [ Oleksandr Shneyder ]
   * New upstream release (4.0.5.1):
diff --git a/src/onmainwindow.cpp b/src/onmainwindow.cpp
index c574070..41de685 100644
--- a/src/onmainwindow.cpp
+++ b/src/onmainwindow.cpp
@@ -5555,47 +5555,154 @@ void ONMainWindow::slotSndTunnelFailed ( bool result,  QString output,
 #ifdef Q_OS_DARWIN
 void ONMainWindow::slotSetModMap()
 {
-    if(!nxproxy)
-    {
+    if (!nxproxy) {
         return;
     }
-    if (kbMap.isEmpty ())
-    {
-        QProcess pr(this);
-        pr.setProcessEnvironment(QProcessEnvironment::systemEnvironment());
-        pr.start("/opt/X11/bin/xmodmap -pke");
-        pr.waitForFinished();
-        kbMap=pr.readAllStandardOutput();
-        pr.start("/opt/X11/bin/xmodmap -pm");
-        pr.waitForFinished();
-        QString modifiers=pr.readAllStandardOutput();
-        x2goDebug<<"modifiers: "<<modifiers;
-        kbMap+="clear shift\nclear lock\nclear control\nclear mod1\nclear mod2\nclear mod3\nclear mod4\nclear mod5\n";
-        QStringList lines=modifiers.split("\n",QString::SkipEmptyParts);
-        for(int i=0; i<lines.count(); ++i)
-        {
-            QStringList parts=lines[i].split(" ",QString::SkipEmptyParts);
-            if(parts.count()<2)
-            {
-                continue;
+    if (kbMap.isEmpty ()) {
+        QProcess pr (this);
+        QProcessEnvironment tmp_env = QProcessEnvironment::systemEnvironment ();
+        QString path_val = tmp_env.value ("PATH");
+
+        /* Let's set a reasonable default value if none is provided. */
+        if (path_val.isEmpty ()) {
+            /* Prefer the default MacPorts prefix. */
+            path_val = "/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin:/opt/X11/bin";
+            tmp_env.insert ("PATH", path_val);
+        }
+
+        pr.setProcessEnvironment (tmp_env);
+
+        QStringList key_map_fetch_args;
+        key_map_fetch_args << "-pke";
+        pr.start ("xmodmap", key_map_fetch_args);
+        bool key_map_fetch_ret = pr.waitForStarted ();
+
+        if (!key_map_fetch_ret) {
+            handle_xmodmap_error (pr);
+        }
+        else {
+            key_map_fetch_ret = pr.waitForFinished ();
+
+            if (!key_map_fetch_ret) {
+                handle_xmodmap_error (pr);
             }
-            QString mod=parts[0];
-            if(mod == "shift" || mod=="lock" || mod=="control" || mod=="mod1"|| mod=="mod2"|| mod=="mod3"|| mod=="mod4"|| mod=="mod5")
-            {
-                for(int j=1; j<parts.count(); ++j)
-                {
-                    if(parts[j].indexOf("(")==-1)
-                    {
-                        kbMap+="add "+mod+" = "+parts[j]+"\n";
+
+            kbMap = pr.readAllStandardOutput ();
+
+            QStringList mod_fetch_args;
+            mod_fetch_args << "-pm";
+            pr.start ("xmodmap", mod_fetch_args);
+            bool mod_fetch_ret = pr.waitForStarted ();
+
+            if (!mod_fetch_ret) {
+                handle_xmodmap_error (pr);
+            }
+            else {
+                mod_fetch_ret = pr.waitForFinished ();
+
+                if (!mod_fetch_ret) {
+                    handle_xmodmap_error (pr);
+                }
+
+                QString modifiers = pr.readAllStandardOutput ();
+                x2goDebug << "modifiers: " << modifiers;
+
+                /* Reset all modifiers first. */
+                kbMap += "clear shift\nclear lock\nclear control\nclear mod1\nclear mod2\nclear mod3\nclear mod4\nclear mod5\n";
+
+                /* And set them back again. */
+                QStringList lines = modifiers.split ("\n", QString::SkipEmptyParts);
+                for (int i = 0; i < lines.count (); ++i) {
+                    QStringList parts = lines[i].split (" ", QString::SkipEmptyParts);
+                    if (parts.count () < 2) {
+                        continue;
+                    }
+
+                    QString mod = parts[0];
+                    if ((mod == "shift") || (mod == "lock") || (mod == "control") || (mod == "mod1") || (mod == "mod2") || (mod == "mod3") || (mod == "mod4") || (mod == "mod5")) {
+                        for (int j = 1; j < parts.count (); ++j) {
+                            if (parts[j].indexOf ("(") == -1) {
+                                kbMap += "add " + mod + " = " + parts[j] + "\n";
+                            }
+                        }
                     }
                 }
+
+                /* Send modified map to server. */
+                QString cmd = "export DISPLAY=\":" + resumingSession.display + "\"; echo \"" + kbMap + "\" | xmodmap -";
+                sshConnection->executeCommand (cmd);
             }
         }
     }
+}
 
-    QString cmd = "export DISPLAY=\":" + resumingSession.display + "\"; echo \"" + kbMap + "\" | xmodmap -";
+void ONMainWindow::handle_xmodmap_error (QProcess &proc) {
+  QString main_text ("xmodmap ");
+  QString informative_text;
 
-    sshConnection->executeCommand (cmd);
+  QProcessEnvironment proc_env = QProcessEnvironment::systemEnvironment ();
+
+  /* If the process has a special env, fetch it. */
+  if (!(proc.processEnvironment ().isEmpty ())) {
+    proc_env = proc.processEnvironment ();
+  }
+
+  switch (proc.error ()) {
+    case QProcess::FailedToStart: {
+      main_text += tr ("failed to start.");
+      informative_text += tr ("This likely means the binary is not available.\n"
+                              "The current search path is: ");
+
+      QString path_val = proc_env.value ("PATH", "unknown");
+
+      /* Add a newline every 100 characters. */
+      for (std::size_t i = 100; i < static_cast<std::size_t> (path_val.size ()); i += 100) {
+          path_val.insert (i, "\n");
+      }
+
+      informative_text += path_val;
+      break;
+    }
+    case QProcess::Crashed: {
+      main_text += tr ("returned a non-zero exit code or crashed otherwise.");
+      informative_text += tr ("Execution failed, exit code was: ");
+      informative_text += QString::number (proc.exitCode ());
+      break;
+    }
+    case QProcess::Timedout: {
+      main_text += tr ("didn't start up in time.");
+      informative_text = tr ("This error shouldn't come up.");
+      break;
+    }
+    case QProcess::WriteError: {
+      main_text += tr ("didn't accept a write operation.");
+      informative_text = tr ("It is probably not running correctly or crashed in-between.");
+      break;
+    }
+    case QProcess::ReadError: {
+      main_text = tr ("Unable to read from xmodmap.");
+      informative_text = tr ("It is probably not running correctly or crashed in-between.");
+      break;
+    }
+    case QProcess::UnknownError: {
+      main_text += tr ("encountered an unknown error during start up or execution.");
+      break;
+    }
+    default: {
+      main_text += tr ("experienced an undefined error.");
+      break;
+    }
+  }
+
+  if (!informative_text.isEmpty ()) {
+    informative_text += "\n\n";
+  }
+
+  informative_text += tr ("X2Go Client will now terminate.\n\n"
+                          "File a bug report as outlined on the <a href=\"http://wiki.x2go.org/doku.php/wiki:bugs\">bugs wiki page</a>.");
+
+  show_RichText_ErrorMsgBox (main_text, informative_text);
+  trayQuit ();
 }
 #endif
 
diff --git a/src/onmainwindow.h b/src/onmainwindow.h
index 5674c2c..2ae1269 100644
--- a/src/onmainwindow.h
+++ b/src/onmainwindow.h
@@ -1148,6 +1148,7 @@ private slots:
     void slotStartNewBrokerSession ();
 #ifdef Q_OS_DARWIN
     void slotSetModMap();
+    void handle_xmodmap_error (QProcess &proc);
 private:
     QTimer* modMapTimer;
     QString kbMap;

--
Alioth's /srv/git/code.x2go.org/x2goclient.git//..//_hooks_/post-receive-email on /srv/git/code.x2go.org/x2goclient.git


More information about the x2go-commits mailing list