Use service path instead of Exec line to store TerminalApplication
Open, Needs TriagePublic

Description

This came again to my mind, because of the discussion in https://invent.kde.org/plasma/plasma-desktop/-/merge_requests/38#note_131833.

Currently we store the exec line when selecting a default terminal, this has the following problems:

  • We don't know the service it belongs to
  • We don't update the value of the desktop file of the terminal program changes(lets say through an update)
  • We don't use the desktop exec parser

Also we have a few other issues:

  • The value is often directly read from the desktop file
    • Not all terminals get supported with the correct command line parameters, especially if we want to support more external terminals we don't want to have the logic in multiple places.
  • We don't call KToolInvokcation::invokeTerminal which is supposed to be the central place for invoking terminals and stuff. This method does the command creation and also supports windows terminals. Because konsole is hardcoded as the default value for the config read accesses this won't work on windows(also the KCM does not exist there, obviously ;) )

My suggestion is:

  • Adding a simple static method to KToolInvocation which will just read the TerminalApplication. Then all the hardcoded config read accesses get replaced.
  • Also save the service path of the terminal in the KCM
    • Use the service path to get the exec line in the newly created method mentioned above. The old value can be used as a fallback. This way we also ensure compatibility.
  • Create a new method which will create the string+args that we can put into our QProcess, this will take the command that should be executed in the terminal as a parameter. In case we don't want to launch a detached process(like KToolInvokcation::invokeTerminal does) we can use this and avoid hacks/duplicate code. Then we can also refactor and reuse the KToolInvocation logic for windows.

After that we are far more flexible and robust with our default terminal application config and can also fix the cases where users are unhappy that their config gets ignored :)

alex created this task.Nov 9 2020, 7:44 PM
alex updated the task description. (Show Details)Nov 9 2020, 8:26 PM

Will my terminal always be a service? For example if I manually select a random binary in the kcm?

alex added a comment.Nov 10 2020, 7:49 AM

;Then the KCM would need to delete the old service entry and write the exec line in the config. Then the The old value can be used as a fallback. case will happen and all is good :)

alex added a comment.Nov 10 2020, 10:07 AM

@davidre But actually one implementation detail I am not sure about: Should we write the path if we select a random binary should we also write that in the new key? I think it would be a good idea, because then we consistently use only one config key and can remove the old one in KF6.

alex added a comment.EditedNov 11 2020, 10:22 AM

@dfaure How should we handle the case where we want to use/not use the --hold functionality? Maybe adding an enum value to the proposed method which will create the command? Then we will be very flexible and if we need to differentiate between more cases in the future we can just add new values to the enum.

This way we would not need the proposed method which will "just" read the value from the config.

You could use the same trick as BrowserApplication:

  • if it starts with a '!' it's a literal command
  • otherwise it's the ID of a desktop file

Obviously not compatible with the existing key for TerminalApplication so this would have to be a different key.

hold/not-hold with an enum sounds good API wise, but you also need to know how each terminal implements it. Instead of hardcoding that in the implementation, maybe let the KCM write it out in a separate kconfig key.
Then the KCM can still hardcode a few known cases (konsole, xterm), but the (advanced) user can specify what his terminal uses as an option.

alex added a comment.Nov 11 2020, 10:46 AM

You could use the same trick as BrowserApplication:

Awesome, will do that!

but you also need to know how each terminal implements it.

Currently that is determined when reading the config in KToolInvocation.

Instead of hardcoding that in the implementation, maybe let the KCM write it out in a separate kconfig key.

And I don't think that the KCM should make assumptions on how the implementation should be, currently KToolInvocation handles the implementation when reading the value from the config.

Hmm, this isn't what I said, I think.

I mean the KCM could write out

TerminalService=org.kde.konsole
TerminalHoldOption=--noclose

or

TerminalService=!xterm
TerminalHoldOption=-hold

etc.

alex added a comment.Nov 11 2020, 11:35 AM

But we often have Konsole as the default terminal, by your proposal we would need to have the information that --noclose is the hold option twice: In the KCM and in KToolInvocation. Which is why I think we are better of just doing it in KToolInvocation and reusing that in the rest of the codebase.

Then the KCM just says what terminal should be used and KToolInvocation knows how it should be used :)

In KF6 (where we can drop compatibility), the information about --noclose would be only in the KCM, not in ktoolinvocation any longer.

Then the KCM just says what terminal should be used and KToolInvocation knows how it should be used :)

This logic breaks as soon as the user chooses another terminal appication.
KToolInvocation doesn't know the name of the option that gnome-terminal wants for this...

I think Alex' point was that KToolInvocation needs to have the default values for when the user hasn't set anything. So it needs to have some degree of coverage for konsole and xterm at which point that information would be duplicate.
The config.readEntry("TerminalHoldOption", "--noclose") scenario essentially.

A problem which is surely solved by putting a helper function somewhere (in kservice?) QString holdOptionForService(...) that the KCM can use as well as ktoolinvocation.

+1 to the user setting the hold option via the KCM when choosing an unknown terminal though.

alex added a comment.Nov 11 2020, 12:54 PM

+1 to the user setting the hold option via the KCM when choosing an unknown terminal though.

Agreed. Then the KCM should show this option if the user selects an unknown terminal. And if the terminal is known the user is not confronted with these settings.

A problem which is surely solved by putting a helper function somewhere (in kservice?) QString holdOptionForService(...) that the KCM can use as well as ktoolinvocation.

Please note that the -e option to execute the given string in the terminal is not always the same, right now KToolInvocation checks the known values and makes otherwise a smart guess. So the method should not be whether or not the hold option, but the terminal itself is known ;)
Then we could also have an TerminalExecuteOption key.

Fair enough.

alex added a comment.Nov 11 2020, 1:58 PM

You could use the same trick as BrowserApplication:

if it starts with a '!' it's a literal command
otherwise it's the ID of a desktop file

Obviously not compatible with the existing key for TerminalApplication so this would have to be a different key.

@dfaure I just played around with it an one thing made me wonder: When I choose a different browser application I don't see a !, but rather a local .desktop file with NoDisplay=true is created.

But the approach you suggested still makes sense to me. How do you propose we call the new key (I have no preference)?

I'd say keep it consistent with BrowserApplication. If it no longer does the '!' thing then don't either. Creating a local desktop file keeps things easier on the consumer side.

I already proposed a name, above :)

alex moved this task from Backlog to Done on the KF6 board.Apr 23 2021, 7:35 PM