[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