amodm / webbrowser-rs

Rust library to open URLs in the web browsers available on a platform

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Please support non-GTK/GNOME-family options in the non-xdg-utils fallbacks

ssokolow opened this issue · comments

If you're going to support gvfs-open and gnome-open to solve #2 in situations where xdg-utils hasn't been installed and $BROWSER is unset, then I suggest adding the following two things to your fallback chain:

  1. kioclient exec <URL> (KDE's equivalent to gvfs-open)
  2. x-www-browser <URL> (This should go at the end of the fallback chain. On Debian-family systems (eg. Ubuntu, Mint), it invokes whatever browser is configured as default at the system-wide level and, as it's maintained by the package manager, it's guaranteed to be present and valid as long as at least one browser is installed... even if that means falling bact to lynx or links in a terminal.)

Also, if you want to be a little bit smarter in mixed installations, check whether the XDG_CURRENT_DESKTOP environment variable says KDE to determine whether kioclient exec <URL> should come before or after the g... ones in the precedence order.

If you're receptive to these changes, I wouldn't mind taking a shot at them myself.

(I just finished patching dialog-rs to support KDialog with precedence relative to Zenity depending on whether XDG_CURRENT_DESKTOP is KDE. The upstream is self-hosted, so all I could do was fire off an e-mail with that link.)

That'd be great, thanks

OK. I'll try to fit it in today.

Also, I'm curious why you chose to explicitly whitelist Linux and supported BSDs, rather than specifying something like this:

#[cfg(all(unix, not(target_os = "macos")))]

After all, things like xdg-open, KDE, and GNOME do work on platforms like Solaris.

Was easier/safer for me to be explicit about it, as I didn't have those (unix but non-macos non-linux) platforms easily available to test.

Was easier/safer for me to be explicit about it, as I didn't have those (unix but non-macos non-linux) platforms easily available to test.

I appreciate your intent, but artificially limiting the portability of a project, based not on the supported APIs, but based on what you've directly tested with, is not the way to do it.

Here are two other examples which elicited ill-will when others did them:

  1. Linux ports of games like Runner 2 artificially limiting proper behaviour of their gamepad input to controllers that actually report being genuine Microsoft controllers. (ie. Needlessly re-creating the XInput limitation that resulted in x360ce, resulting in the need to use xboxdrv's lesser-known x360ce-like mode.)
  2. Websites detecting based on browser name rather than supported features. (I believe Google caught some flak for doing that with YouTube to the detriment of Microsoft Edge.)

Feel free to make a big sign saying that you only officially support platforms X, Y, and Z, but don't definitively lock out platforms just because you can't prove they work.

I feel you may be over extending the ill-will analogy here, as this project is MIT/Apache licensed, and people are free to derive works from this, and thus modify it in whatever way they deem right for their use (this being a library and not an application). Moreover, I've not blocked out any PR that extends the number of platforms supported.

I've largely run with the intent of minimising bad surprises, and so will continue to be specific about the platforms that are supported, while relying on people like yourself to extend/validate the supported platforms. I hope you can understand it, even if you disagree.

I agree that the degree is certainly different, but it just rubs me the wrong way to see that, after the UNIX ecosystem learned "feature detection, not platform detection" (Good old GNU Autotools. ./configure && make && make install), and web developers had to re-learn that lesson, people are still making that same mistake.

On a niche platform, manpower to investigate problems will already be in shorter supply, so it's unfair to them to put up artificial hurdles. I'd compare it to the motivation difference between proper open-source and "e-mail me if you want the source code".

To be honest, I feel strongly enough about this that, once I have tools that depend on this which I'm ready to share, I may start maintaining a friendly/upstream-following fork for them to depend on. (I'd still send all other patches up to you... I'd just maintain a fork which adds that cfg change on top of whatever you release, upload it to crates.io, and let my projects depend on that instead to ensure you don't risk becoming the one guaranteed obstacle to my creations working on niche POSIX platforms.)

If it helps, think of it like this. What if everyone did what you're doing? Niche platforms would never get off the ground with all the demotivating, non-productive busywork of patching out thousands of spurious platform checks and keeping said patches applying in the face of updates until they feel their project has enough staying power for the patches to be worth trying to upstream. That's why things like GNU Autotools are made to normalize "feature detection, not platform detection".

I'm a fan of GNU Autotools but this is not one of those scenarios. In a typical autotools setup, it'll lead to a compile time failure if there are any missed rules/pragmas for the underlying platform. In this scenario, I'm invoking a local command, which means that compile time would pass, but it'll be a runtime failure, which can be bad for non-technical users.

That, coupled with the fact that one can just set the BROWSER env variable in niche unix platforms, should suffice. However, to enable that open_on_unix_using_browser_env should be configured for all unix family, which I agree should be done, and should cater to the scenario you're describing.

That, coupled with the fact that one can just set the BROWSER env variable in niche unix platforms, should suffice. However, to enable that open_on_unix_using_browser_env should be configured for all unix family, which I agree should be done, and should cater to the scenario you're describing.

Except that the whole point of xdg-open is to be what you're trying to "reinvent badly". In a situation like this, it's the platform's responsibility to ensure that it's either functional or missing as a single shared dependency.

Having the system set BROWSER for you is not the standard way to accomplish that.

In this scenario, I'm invoking a local command, which means that compile time would pass, but it'll be a runtime failure, which can be bad for non-technical users.

Except that's a false sense of security. It's entirely possible to have a Linux system with none of those commands present and you've already got your code such that it effectively treats "command missing" and "command returned an error" equivalently.

...not to mention that, at least once, I worked on a Linux machine where the file associations were broken and commands like xdg-open did weird things like trying to launch URLs in the default handler for application/octet-stream, which was either a text editor or a hex editor.

It doesn't make sense to approach the problem from your perspective. At some point, you have to trust that the runtime environment is sane.

The idea here isn't to reinvent xdg-open 😄- it has it's own place.

xdg-open is a script, and as such is closer to a user tool, which specifically focusses on opening the default web browser, or a bunch of fallbacks, to open a url.

webbrowser-rs is a library whose objective is to expose simple APIs (thus developer centric, not user centric) to open any browser they want, with default as one of the options. For the default option, it uses xdg-open.

What my take away from this thread has been that xdg-open may be available in more environments than what I've included, even if not guaranteed to be there. I think it's probably worthwhile to include xdg-open under a #[cfg(all(unix, not(target_os = "macos"), not(target_os = "android")))].

What my take away from this thread has been that xdg-open may be available in more environments than what I've included, even if not guaranteed to be there.

Yeah. They've put a lot of effort into writing xdg-open as a highly portable shell script for that reason. POSIX requires that a Bourne-compatible shell exist at /bin/sh and the intent is that it should be usable on any OS where #!/bin/sh executes it in a Bourne shell.

I think it's probably worthwhile to include xdg-open under a #[cfg(all(unix, not(target_os = "macos"), not(target_os = "android")))].

Good catch with android. I'm so used to thinking about how Google intended the POSIX APIs to be an unimportant implementation detail from the applications' perspective that I forgot that, as a non-Java language, Rust would see Android as unix.

Also, there's actually a BSD you're currently ruling out with your existing approach. target_os = "dragonfly" was forked from FreeBSD 4.8 due to disagreements over what algorithms should be used for certain things in the kernel and they still continue to share code back and forth.