11

I'm currently having difficulties with a very simple launcher application that's intended to display a webpage and have some buttons to launch a game. When you click a link inside of the launcher it is intended to simply launch your default webbrowser with the link, rather than accepting and handling navigation requests.

However, when launched via Steam, links fail to open in a new webbrowser. Exact behavior depends on the environment, I've had reports of copies of gvfs-open and xdg-open hanging, though on my environment it simply gives mouse indication that firefox is opening for a split second and does nothing (including no processes launched at all according to strace, possibly has something to do with KDE's message passing system, I don't know). Vexingly enough, there are also reports that it just works fine. And so I'm having quite a problem hammering down the exact issue as a result.

I've managed to narrow down the issues to Steam modifying the LD_LIBARRY_PATH of the executable to use Steam's Linux platforms. I've bundled all of the libraries needed by the launcher with the launcher.

Here is a minimal reproducible guide:

main.cpp

#include <QApplication>
#include <QWebFrame>
#include <QDesktopServices>
#include <QNetworkRequest>
#include <QMessageBox>
#include <QWebView>

class WebPage : public QWebPage {
public:
  bool acceptNavigationRequest(QWebFrame*, const QNetworkRequest &request, NavigationType) {
    QDesktopServices::openUrl(request.url());
    return false;
  }
};

class WebView : public QWebView {
public:
  QWebView* createWindow(QWebPage::WebWindowType) {
    WebView* res = new WebView;
    WebPage* page = new WebPage;
    res->setPage(page);
    return res;
  }
};

int main(int argc, char *argv[]) {
  QApplication a(argc, argv);

  WebView v;
  v.load(QUrl("http://example.com/"));
  v.show();

  return a.exec();
}

launcher.pro

QT += core gui network webkitwidgets widgets

TARGET = launcher
TEMPLATE = app

SOURCES = main.cpp

You will also need to copy and bundle the following libraries (standard Qt deployment):

libQt5Widgets.so libQt5Gui.so libQt5Core.so libQt5Network.so libQt5WebKitWidgets.so libQt5WebKit.so libQt5MultimediaWidgets.so libQt5OpenGL.so libQt5PrintSupport.so libQt5Multimedia.so libQt5Sensors.so libQt5Quick.so libQt5Qml.so libQt5Sql.so libQt5Positioning.so libQt5DBus.so libicui18n.so libicuuc.so libicudata.so libssl.so libcrypto.so libstdc++.so libgcc_s.so

And in a subdirectory called platforms:

libqxcb.so

And then finally a script to tie it together:

launch_launcher.sh

#!/bin/sh -e

cd "$(dirname "$0")"

LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./launcher

Finally, have steam installed and set it's LD_LIBRARY_PATH as your own and export it and run launch_launcher.sh (these exact paths depends on your steam installation.)

Essentially, if you remove $LD_LIBRARY_PATH from the launch_launcher script so that the line reads only LD_LIBRARY_PATH=. ./launcher then the links work. However with $LD_LIBRARY_PATH enabled links do not work. We need $LD_LIBRARY_PATH working in order to use the Steam Linux platform libraries (which makes the game work.)

What's the best way to troubleshoot this issue? How can I find the responsible library and exclude it or otherwise workaround this problem?

OmnipotentEntity
  • 16,531
  • 6
  • 62
  • 96
  • in launch_launcher.sh can you output the whole LD_LIBRARY_PATH value, and try explicitly setting that in future launches? i.e. `echo $LD_LIBRARY_PATH # sample-output: .:A:B:C:D:E` modified launcher script: `LD_LIBRARY_PATH=.:A:B:C ./launcher` – Fox Mar 20 '15 at 12:43
  • as for solving the problem after isolation, I'll need to look deeper into that – Fox Mar 20 '15 at 12:46
  • @Fox, `LD_LIBRARY_PATH` is whatever Steam sets it to. This is usually actually quite long and it's different from system to system and user to user (because Steam installs itself under `~/.steam/`) Simply changing `LD_LIBRARY_PATH` won't help, because I need the full Steam provided `LD_LIBRARY_PATH` for the game, but the Steam provided `LD_LIBRARY_PATH` also seems to be interfering with `QDesktopServices`. So it's not a matter of finding the right `LD_LIBRARY_PATH` because it doesn't seem to exist. – OmnipotentEntity Mar 20 '15 at 19:51
  • I'll add an "answer" to explain it better. – Fox Mar 22 '15 at 06:12

2 Answers2

1

So, I'm addressing this part (as explained in an earlier question comment)

What's the best way to troubleshoot this issue? How can I find the responsible library

and not this

and exclude it or otherwise workaround this problem?

the reasoning being that if you're using a steam-supported Linux config, LD_LIBRARY_PATHs are supposed to be a last-resort setting for any app (especially commercial ones). If it messes with other libraries/apps, it's their bug.

Your approach in isolating a repro is fundamentally valid that way. The logical extension is to (like in the comment) continue with:

LD_LIBRARY_PATH={myentry}:A:B:C
./launcher

instead of

LD_LIBRARY_PATH={myentry}:${LD_LIBRARY_PATH}
./launcher

this allows you to cherry pick among "A:B:C" (which is the current LD_LIBRARY_PATH including Steam library entries) and determine leaving which entries out makes your app start working again.

As for addressing it, it depends on several variables on your system (your distro, other installed libs under LD_LIBRARY_PATH, your Qt version vs KDE's Qt version). You could try:

  1. googling for workarounds - it may be as simple as a replacement library file, or Qt patch, or a single function you call from your main function (similar to @fbucek's answer).
  2. logging bug-reports with Steam and Qt - so this workaround isn't specific to your system, and isn't broken again with the next Steam update.

edit: you observe that it is QDesktopServices which is affected - my most likely guess would be differing Qt versions between two of KDE, yours and Steam.

Fox
  • 2,078
  • 17
  • 18
  • Sorry, I misunderstood the intent of your post. You are completely correct that this is a valid way of troubleshooting this issue. I apologize for being standoffish. I'll give this a shot the next time I work on this issue and I'll keep you posted. – OmnipotentEntity Mar 22 '15 at 19:01
  • no worries :) - the original comment was a bit terse. Hope you do get a solution. – Fox Mar 23 '15 at 10:06
0

I guess you problem is more complex. Just thought what you can try.

1) You app maybe does not need to use LD_LIBRARY_PATH

Not to mess with LD_LIBRARY_PATH in your app, you can put library search path into you program. ( linux solution )

App structue
/app/bin
/app/lib    // where all my libraries are including Qt libraries

.pro file

QMAKE_RPATHDIR = \$\$ORIGIN/../lib
QMAKE_LFLAGS_RELEASE += \'-Wl,-rpath,$${QMAKE_RPATHDIR}\'
QMAKE_RPATHDIR =

( do not remember why it looks this stupid in my old app - but it works and at this moment I am not on linux to simplify it )

2) Set LD_LIBRARY_PATH only for processes within your app ( not to make LD_LIBARY_PATH too complex. path to your app, steam etc. )

I do not know in what context is new browser executed but if it is your app you can use this aproach. This ensures only processes within your app will have this LD_LIBRARY_PATH

You can set LD_LIBRARY_PATH within your app using

setenv("LD_LIBRARY_PATH", yourPath.toLatin1().data(), 1)
// You can test it using
QProcessEnvironment::systemEnvironment().value("LD_LIBRARY_PATH");

I guess you don use QProcess so, setting environment for process itself is out of question.

fbucek
  • 1,647
  • 13
  • 22