-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Add support for kioclient and x-www-browser #17
Conversation
(This alias is created and maintained by Debian's "alternatives" system, which is integrated with the APT package manager. It serves to act as a system-wide default on Debian-family distros (eg. Ubuntu, Mint) which applications can fall back to if the user hasn't specified a preference.)
`kioclient exec` is KDE's equivalent to gvfs-open. In this version using a fixed precedence order, it is added after all entries which existed in the previous released version to ensure that it will not change the behaviour for users of non-KDE desktops. Were this starting a new major version, I would put kioclient ahead of gvfs-open and gnome-open in the precedence order since it's more common to find GTK+ applications on KDE desktops (and, thus `gvfs-open` too) than to find KDE applications on GNOME desktops.
(This maximizes the chance of doing what the user expects if their KDE and GTK/GNOME URL-handling preferences disagree.) Fixes #16
Oops. Sorry about that failed Travis-CI run. I forgot to run (I don't have it set up to run automatically because there are certain aspects of my coding style where |
Hmm. It looks like adding I can think of various ways to work around that (eg. setting |
Consistency of behaviour (currently non-blocking) is important, so if some of those commands invoke a blocking behaviour, can you figure out how to make them comply with the existing behaviour? Manually running the commands on your terminal may indicate if they are blocking in nature or not. Modifying tests to mock or skip wouldn't be productive because it may hide behavioural inconsistencies of this kind. |
Ahh. It's probably the |
...and, looking at your (Setting EDIT: Yeah. If I invoke |
...and looking at (The other options are to invoke things like |
Hmm. It looks like
The
In other words, ...and |
While poking through KDE:
MATE:
Xfce:
I don't want to go poking through every tool out there, but the source to I believe |
To make a long story short:
As for your question, I can certainly make The best you can do is introduce a race condition by polling on Fundamentally, there's no common standard for applications to report "I successfully finished starting up" to their parents that browsers implement and there's also no standard way to make it predictable whether invoking a browser will block. Firefox and Chromium, for example, will both exit quickly if they decide to open the URL in a pre-existing browser session or block until the browser is closed if not. |
Thanks for bringing out potentially blocking behaviour of I also agree with your assessment of the potential blocking behaviour of For the time being, let's focus on bringing this PR to a closure. We can discuss the philosophy piece on #16 |
My point was to illustrate that blocking vs. non-blocking has to be solved across all of them. It was a lurking issue all along.
The documentation isn't 100% clear on what As for browsers:
Those are all the browsers I happen to have installed at the moment. In fact, the proper way to think about it is "Like most processes ( |
All good points. I'm going to noodle over this issue until I've developed a consistent thought process on the blocking part, as well as fix the tests. Until then, the PR remains open. |
Understood. Poke me when you're ready. |
src/lib.rs
Outdated
.or_else(|_| -> Result<ExitStatus> { | ||
Command::new("kioclient").arg("exec").arg(url).status() | ||
}) | ||
.or_else(|_| -> Result<ExitStatus> { Command::new("x-www-browser").arg(url).status() }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll recommend you modify this to something like
.or_else(|e| -> Result<ExitStatus> {
if let Ok(child) = Command::new("x-www-browser").arg(url).spawn() {
return Ok(ExitStatusExt::from_raw(0));
}
Err(e)
})
to allow for the tests to pass for now. It'll allow me to accept the PR. I'm realising that a larger fix for making the behaviour consistent, and reflecting those in the tests, will take me some time. So let's focus on closing this out for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I'm just winding down for bed but I should have a commit for you tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed the change but it's still blocking on the browser.
I have a headache and want to get to bed early, so I'll have to look into it further tomorrow, but I know it's not kioclient exec
because, if I temporarily set my KDE handler for http://
and https://
URLs to something that's not already running, kioclient exec
will launch the expected browser but will not block.
That leaves two possibilities I can think of off the top of my head:
- The code snippet you proposed is insufficient to keep it from waiting on a spawned child. I'll have to experiment tomorrow to rule this out.
- Travis-CI's configuration has changed since you last ran a test and, if you were to ask it to re-test your current
HEAD
, that would timeout and fail too.
I'm fairly certain it's not a difference between how my and Travis-CI's copies of commands behave, because we're both running systems based on Ubuntu Xenial (16.04 LTS).
I can see three ways option 2 might come about:
- Travis-CI might have started waiting for background processes to exit before considering a test run finished.
- Travis-CI might have changed the default browser.
- Travis-CI might have upgraded to a version of the browser which behaves differently under your test conditions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran a new build on master
HEAD just now, and it passed.
(Temporary solution to resolve by far the most likely place for this command to block in headless test conditions.)
A few updates. Firstly, I'll be merging this PR, and figure it out from there. Regarding the issues with the tests, I feel your contribution has only brought out the root problem, than caused it. So the onus is on me to figure it out. Thanks for the contribution, as well as other insights. |
No problem and good to know. I was starting to worry that Travis-CI just wanted to try to drive me crazy. |
Oh, I just noticed that I forgot to update the README to acknowledge |
I'll do that, after figuring out why the tests produce different outcomes in different scenarios, and fixing them. |
Speaking of fixing tests, what I'd suggest as the ideal solution for the end-to-end testing you seem to want is to add something like Hyper as a dev dependency and have the tests spin up an HTTP server which will service one request and then exit. Then, you can even do a true verification that the URLs fed to the function are what are getting requested by the browsers. |
Makes sense. Thanks. |
An implementation of the changes discussed in issue #16
I tried to preserve the existing code structure as much as possible in the face of needing to check
std::env
for whetherkioclient
orgvfs-open
andgnome-open
should take precedence.I did some quick checks on my end by unsetting
BROWSER
, and/or commenting out the other entries and everything appears to be working.For a more robust means of integration testing, one approach I've used before is to mock the commands as follows:
echo "SUCCESS: $0" > result.log
and equivalent batch files)cargo test --no-run
./target/debug/webbrowser-*
binary manually, withPATH
set to contain only the folder full of whichever set of mocks that particular test requires.