"Open with" in Qt5 application

I think this is not a bug, but a feature request for Tracker.

1 Like

Ha, I actually ran into this exact same thing some years ago, and filed a ticket about it: #11893 (When a shell script is the handling application for a mimetype, registrar does not propagate arguments to it) – Haiku

TL;DR: Despite the Be Book saying that, BeOS still sent RefsReceived messages to applications with B_ARGV_ONLY. However, nobody could think of a good reason why this is the case, so we can probably safely use B_ARGV_ONLY, indeed. I did some preliminary investigation but never found the time to figure out where the change needs to occur for that.

1 Like

Hm. Apps with B_ARGV_ONLY flag not showed in OpenWith menu - https://xref.landonf.org/source/xref/haiku/src/kits/tracker/OpenWithWindow.cpp#1635

That sounds like Tracker does not handle them properly and it was put there as a hack, then.

1 Like

Good to see I’m not the only one having this expectation. I think this would be very helpful indeed, not only for ported applications using different toolkits but also for easily using any scripts for open with. It also sounds like this would not really break anything even if this would be a change of current behavior.

Well, I see it the other way around. The application says that it does not handle refs, so Tracker can exclude them from that list. That may in fact be the reason that caused this flag to be introduced: just so that Tracker “Open With” could filter out apps that won’t be handling files anyway.

For apps that do handle files, they should handle RefsReceived. Converting to command-line args is a hack, and add more confusion, because now, you have no idea if an app can handle files or not. Even if it’s B_ARGV_ONLY, maybe it can accept files as command line arguments. But that would be only a wild guess.

Imagine your app is ported from Windows and uses the / style of arguments. Converting paths to arguments would cause it to do all kind of weird and unwanted things.

But that’s true the other way round, too: If an app does not specify B_ARGV_ONLY the assumption that it handles a ref message is only a wild guess as well.

Also, if an app cannot handle opening files then there should also be no mimetype registration. I think it’s save to assume that an app which registers mimetypes is able to open files. Likewise it should be save to assume if an app specifies B_ARGV_ONLY it should be able to handle command line arguments, otherwise specifying this flag would be wrong.

Yes, ideally this would rather be opt-in, but I suspect it was a somewhat late addition to the API, and doing it that way would have excluded perfectly working apps from the “Open With” list, or something.

Not necessarily, for example DiskProbe can open any file and does not care about MIME types.

Handling command line arguments does not imply in any way that it is save or even going to work at all to pass a file path through argv[1].

That example is actually the other way round and I think unproblematic (DiskProbe can open files as I understand it). But could there be a valid case a an app registering support for certain file types but not being able to open files? I don’t think that’s plausible.

But files that claim to support certain file types usually do. Especially for ported applications from Linux, FreeBSD or Windows. On these systems opening files passed as argv is the usual way how “open with” like functionality works.

I don’t know, but this might not be true for BeOS apps. If so, I assume they would likely implement RefsReceived, or not? Or how else would they accept files?

But if you think B_ARGV_ONLY is not save to indicate that an application should get files passed as arguments than probably a spearate launch flag should be added for that purpose. I still wonder then however what exact use case B_ARGV_ONLY is for. Nobody seems to really know :slight_smile:

It seems pretty clear to me: B_ARGV_ONLY means “don’t list this app in “Open With” dialog, because it does not handle RefsReceived so it won’t work”. That’s probably the only thing it does.

There is another function for this flag (from BeBook): BRoster::Broadcast() - Sends the message to every running application, except to those applications (B_ARGV_ONLY) that don’t accept messages. The message is sent asynchronously with a timeout of 0. As is the case for other message-sending functions, the caller retains ownership of the message.

1 Like

i’m pretty sure that flag means “don’t use RefsReceived, instead use argv”

1 Like

Agreed. I thought about this some more and I’m pretty sure it is safe to pass file names as arguments if both of the following are true:

  1. The app declares support for specific file types
  2. The app sets B_ARGV_ONLY

Why? Because with 1) the app declares that it is able to open said file types. And with 2) it declares it cannot handle the RefsReceived message.

There are two standard ways to open files: Some operating systems, like BeOS/Haiku or macOS define a certain message being send to applications. On virtually all systems not doing this applications open files by command line parameter.

If the application supports no standard way of opening files (e.g. it implements a custom message or very specific arguments like --open somefile instead of just somefile) that application should not register as a handler for this file type. Registering as a handler for any file type only makes sense if an application supports some standard way of receiving file names.

Operating systems only supporting argv for opening files work quite well with this assumption.

At the moment, I have experimentally implemented the following:
Added QPA check for flags in application resources: QT:QPA_FLAGS (possible values ​​are Q_REF_TO_ARGV, Q_REF_TO_FORK, Q_KILL_ON_EXIT)

Q_REF_TO_ARGV - modify argv array by received REFS
Q_REF_TO_FORK - for received REFS, award a new instance of the process with the received files as parameters.
Q_KILL_ON_EXIT - to kill the process on exit (in some applications, unfortunately, this is still required, some apps crashed on exit when global static objects deletion)

By default (if no flags are specified), all workarounds are disabled.

You can add flags by simply writing the following line in rdef for an example:
resource (“QT: QPA_FLAGS”) “QT_REF_TO_ARGV | QT_REF_TO_FORK”;

At the moment I have tested this on several programs:
Picard - no flags: open files from Tracker-> OpenWith works fine, drop to application icon in Deskbar works fine, drop to application icon in Tracker works fine
KWrite - no flags: open files from Tracker-> OpenWith works fine, drop to application icon in Deskbar works fine, drop to application icon in Tracker works fine
Notepadqq - QT_REF_TO_ARGV | QT_REF_TO_FORK: open files from Tracker-> OpenWith works fine, drop to application icon in Deskbar works fine, drop to application icon in Tracker works fine

Does it make sense to include it in the release or not?

3 Likes

Just updated the text editor FeatherPad from v1.1.0 to v1.4.0 and while testing it, noticed that this behavior has resurfaced, even though it has the flags QT_REF_TO_ARGV | QT_REF_TO_FORK set.
but opening from terminal works. and also FeatherPad shows in the list of apps in the OpenWith menu, but opens a blank page.
Can this somehow be related to the issues we were having with env VARS?
Any new ideas on how to fix it… again? @3dEyes ? @waddlesplash ?.
PS: v1.1.0 still works though so it doesn’t seem to be a haiku regression.

Just a follow up on this, this what the dev of FeatherPad had to say.

Anyway, mystery solved :slight_smile: Tthe whole story was about non-UTF8 arguments in Haiku
Haiku’s FM doesn’t use UTF8, and because of that, QString::fromUtf8() doesn’t work with argv directly. But once QCoreApplication is called, it fixes the situation by changing argv to UTF8. That’s why there was no problem on Linux or with a Qt-based FM on Haiku. In the patch, I just let Qt do its job first, without assuming that a UTF8 string is received (which is always the case on Linux).

It seems to be a different problem than the one discussed here?.
here is the whole disussion/investigation.

That explanation makes no sense to me. We use only and exclusively UTF-8 everywhere.

The first explanation that was posted there makes more sense: indeed in Haiku, arguments can be passed using a BMessage and the ArgsReceived function instead of through the command line, and QApplication was modified in Haiku to handle this. This allows to send arguments to an already running application, instead of restarting it from scratch everytime we want it to open something.

3 Likes

Exactly. But a lot of Qt applications don’t handle the necessary FileOpen event, as otherwise this is only used on macOS. So if the application was developed with only Linux or maybe Windows in mind it might only handle passing files via argv.

That’s why Qt for Haiku supports that applications can define QT_REF_TO_ARGV flag, which will trigger the BMessages being put into argv. It is admittedly a bit hacky approach.

But otherwise not sure why this does not work in this case. Above it is claimed that the flag is set.

Because, in this case argv was read before the QApplication that would handle refsreceived was created

2 Likes

FeatherPad sends the file to the instance via dbus. This is the main reason why opening files doesn’t work. Look at singleton.cpp and everything will become clear.

1 Like