Skip to content

Revert "notification: Add platform-data and response to ActionInvoked signal"#1831

Open
3v1n0 wants to merge 3 commits intoflatpak:mainfrom
3v1n0:revert-notification-activation-v2-changes
Open

Revert "notification: Add platform-data and response to ActionInvoked signal"#1831
3v1n0 wants to merge 3 commits intoflatpak:mainfrom
3v1n0:revert-notification-activation-v2-changes

Conversation

@3v1n0
Copy link
Contributor

@3v1n0 3v1n0 commented Oct 9, 2025

Sadly reusing the old activation API for v2 by adding more values to the
parameters array was not working well enough for various reasons:

  • We used a DBus return value as a container for multiple (unrelated)
    and generic return values without being able to reuse any kind of type
    check provided by the platform.
  • Despite the API documented these return values as an ordered list of
    items with (ideally) a fixed position, it was not possible to
    maintain such promise in case of an empty parameter was provided by
    the app or - in future - an empty (!= no) response was sent.
    Note how response was referenced as the third parameter of such
    array, while this might have not been possible.
  • It was confusing for both applications using it and portal
    implementing the API, as it was not clear for the portals
    implementations what to pass back to the application when no parameter
    was received or what the application should expect to receive in such
    case as the first array value.

So, let's go back to the v1 state, as this will allow us to provide a
proper ActionInvoked2 implementation.

This also implies breaking the im.reply-with-text category behavior
though, since that's affected by the very same problem.

We're doing this without changing the portal version though, as this
won't break applications expecting a v2 portal anyways.

This reverts commit 3aedb5f.
This partially reverts commit def2ad7


That said, this is not as easy as it should since im.reply-with-text opens the gate to another problematic sitaution, reason why I think we should also modify ActionInvoked2 to not send the parameters as av at all, but rather as s{av} and same for the exported actions: we just send them back an a{sv} with target and response for now.

3v1n0 added 3 commits October 9, 2025 21:17
… signal"

Sadly reusing the old activation API for v2 by adding more values to the
parameters array was not working well enough for various reasons:
 - We used a DBus return value as a container for multiple (unrelated)
   and generic return values without being able to reuse any kind of type
   check provided by the platform.
 - Despite the API documented these return values as an ordered list of
   items with (ideally) a fixed position, it was not possible to
   maintain such promise in case of an empty parameter was provided by
   the app or - in future - an empty (!= no) response was sent.
   Note how `response` was referenced as the third parameter of such
   array, while this might have not been possible.
 - It was confusing for both applications using it and portal
   implementing the API, as it was not clear for the portals
   implementations what to pass back to the application when no parameter
   was received or what the application should expect to receive in such
   case as the first array value.

So, let's go back to the v1 state, as this will allow us to provide a
proper ActionInvoked2 implementation.

This also implies breaking the `im.reply-with-text` category behavior
though, since that's affected by the very same problem.

We're doing this without changing the portal version though, as this
won't break applications expecting a v2 portal anyways.

This reverts commit 3aedb5f.
This partially reverts commit def2ad7
…t response

The text response is affected by the very same problem of ActionInvoked,
but here it's even worse, since we rely on the `org.freedesktop.Application`
API, and thus we can't modify it (unless we decide to add an
ActivateAction2 method too).

So, preserve the previous behavior, but explain what it should be done
in case an application is not providing a target.

We could have used a special parameter of the platform-data too, but it
seems a bit out of scope there.
@3v1n0 3v1n0 force-pushed the revert-notification-activation-v2-changes branch from 24db59b to 3db8c94 Compare October 9, 2025 19:17
@3v1n0
Copy link
Contributor Author

3v1n0 commented Oct 9, 2025

@swick, @jsparber this is the work prior to the new ActivatedAction2, but as said we're still in troubles as the response again creates troubles.

I've not added a commit yet, but I feel we should just send to the apps a vardict also for the action parameter, given the limitation of fdo apps.

@swick
Copy link
Collaborator

swick commented Oct 10, 2025

Yikes, im.reply-with-text makes things even harder :( But great job at finding that issue!

The problem is that this should all work with org.freedesktop.Application, and there we really can't adjust the signature at all. If we use a vardict for ActivatedAction2, it doesn't solve the issue with org.freedesktop.Application.

So I really think we have to find a way to specify things with a av.

@3v1n0
Copy link
Contributor Author

3v1n0 commented Oct 10, 2025

The problem is that this should all work with org.freedesktop.Application, and there we really can't adjust the signature at all. If we use a vardict for ActivatedAction2, it doesn't solve the issue with org.freedesktop.Application.

What I'm saying is: can't we just send as the first and only parameter of the fdo apps av a vardict instead?

Is there any restriction on sending them back the target as standalone value?

@swick
Copy link
Collaborator

swick commented Oct 13, 2025

I'm not sure if I understand. Do you propose to use the first element of parameter in org.freedesktop.Application::ActivateAction and org.freedesktop.portal.Notification::ActionInvoked as a vardict where we then store the actual information (i.e. the target, and potentially other things)?

Isn't that backwards incompatible?

@3v1n0
Copy link
Contributor Author

3v1n0 commented Oct 13, 2025

I'm not sure if I understand. Do you propose to use the first element of parameter in org.freedesktop.Application::ActivateAction and org.freedesktop.portal.Notification::ActionInvoked as a vardict where we then store the actual information (i.e. the target, and potentially other things)?

Yes

Isn't that backwards incompatible?

It is not, but it has not to be since with ActionInvoked2 we need to bump to v3 anyways

@swick
Copy link
Collaborator

swick commented Oct 13, 2025

It is not, but it has not to be since with ActionInvoked2 we need to bump to v3 anyways

Sure, but everything is supposed to work with org.freedesktop.Application::ActivateAction as well, no? And there we can't just bump the version.

If it were just about org.freedesktop.portal.Notification::ActionInvoked then yes, we totally should make it a a{sv}.

@3v1n0
Copy link
Contributor Author

3v1n0 commented Oct 14, 2025

Sure, but everything is supposed to work with org.freedesktop.Application::ActivateAction as well, no? And there we can't just bump the version.

Yes, but we are not changing the signature of the method, we are changing its content and AFAIK, that's defined nowhere in the standard, but rather a portal decision to pass as first argument the target as a string, no?

So if an application is target the notification portal v3, then it has to expect the parameters to contain something else. It's a breaking change, yes. But How many applications really rely on the "target" anyways? And if they are choosing to use a new portal version they should be ready to adapt anyways.

While the apps using libportal can just transparently be transitioned.

If instead we don't want to break with the past we can just likely send to the app the target as first parameter and the vardict as second one, but this is still breaking Gio based applications, as the parameters will still be packed as a tuple as per this change)

Another option is instead to always use the ActivateAction2 in case more parameters are required as in the im.reply-with-text scenario, but this likely break the dbus-activation so not the best imho (even if in this specific case, we expect the application to be running anyways)

@swick
Copy link
Collaborator

swick commented Oct 15, 2025

Yes, but we are not changing the signature of the method, we are changing its content and AFAIK, that's defined nowhere in the standard, but rather a portal decision to pass as first argument the target as a string, no?

True, but apps expect the action to be passed there already. You argue that if apps use notification portal v3, then they have to expect the the value to contain something else; but the code that handles org.freedesktop.Application is completely different from the code that might use the portal to send a notification.

I don't see how this could work.

But How many applications really rely on the "target" anyways?

That's a different argument, and I just don't know.

@jsparber opinions?

@3v1n0
Copy link
Contributor Author

3v1n0 commented Oct 15, 2025

the code that handles org.freedesktop.Application is completely different from the code that might use the portal to send a notification.

I don't see how this could work.

Well, it would just work in the same way it's already working, no?
See: https://gitlab.gnome.org/3v1n0/glib/-/commits/gapplication-dict-action-parameter

With GLib's commit 0144feb41 the signature of that value already changed from being just a single GVariant value to a tuple in case multiple values are passed, so while that was more conservative it was already making such parameter value "unstable".

Now, IMHO we could just switch to something else that is a bit more safer in this regards than returning a tuple of undefined length whose elements are defined by their index.


However, if you want to be conservative, we can just do the same ourselves: if only a parameter (the target) is passed, we use the same logic as before, otherwise we return a vardict instead. And it would just be backward compatible for most scenarios. But honestly I'd prefer to avoid this kind of dualism (that again it is not new).

@swick
Copy link
Collaborator

swick commented Oct 16, 2025

Okay, I think I'm starting to understand. The app has to define the signature of the action anyway, so if the app a specific version of the notification portal, it has to expect the signature a{sv}, and we just dump the info we want in there.

Yeah, okay, I'm convinced.

@3v1n0
Copy link
Contributor Author

3v1n0 commented Oct 16, 2025

Okay, I think I'm starting to understand. The app has to define the signature of the action anyway, so if the app a specific version of the notification portal, it has to expect the signature a{sv}, and we just dump the info we want in there.

Yep exactly... It's the app defining that, we just passed a value for now... I think the issue has actually created by Gio, since it only considered an action to be able to accept one parameter... This had been fixed by @jsparber; of course we couldn't break current apps, so there is still a limitation in the way we expose the args that cannot be 1:1 to what has been passed.

Yeah, okay, I'm convinced.

Good, now, how do we expose all this? I mean documentation-wise, while the ActionInvoked2 docs are easy, we did never document properly the non-exported actions.

@swick
Copy link
Collaborator

swick commented Oct 19, 2025

We could maybe make it easier for us by having a new method to set the "used" version. Currently only the portal will tell the client its version, but what we need here is essentially the client opting-in a specific version, so we can just say that if the client opts-in to version 2, the av in ActivateAction contains a single variant which is a a{sv}.

Then it becomes rather easy because if we operate on a version 2 client, we always have a a{sv}, and the docs can equally just say assume that.

@3v1n0
Copy link
Contributor Author

3v1n0 commented Oct 20, 2025

We could maybe make it easier for us by having a new method to set the "used" version. Currently only the portal will tell the client its version, but what we need here is essentially the client opting-in a specific version, so we can just say that if the client opts-in to version 2, the av in ActivateAction contains a single variant which is a a{sv}.

That's an option too, although I feel it's something that can be prone to races, unless we allow this to happen only as first method call ever, at the same time why an application should not know what version of the portal is currently running on?

@swick
Copy link
Collaborator

swick commented Oct 20, 2025

The problem I see is that the portal can't just change something in a new version because some clients will only support older versions. So you'd have to switch the signature based on if the notification contains something from version 2. That seems like a recipe for disaster, and people will get it wrong.

We could maybe add a version field to the notification vardict instead?

@3v1n0
Copy link
Contributor Author

3v1n0 commented Oct 20, 2025

The problem I see is that the portal can't just change something in a new version because some clients will only support older versions. So you'd have to switch the signature based on if the notification contains something from version 2. That seems like a recipe for disaster, and people will get it wrong.

Well... Don't think it's a portal problem, if we document things properly TBH. Not to mention that "disaster" is very unlikely to happen as really I'm not aware of any implementation taking care of the "target" parameter.

We could maybe add a version field to the notification vardict instead?

That's maybe better... But, we may then have the other problem: applications not setting the version and thus they'll stick to version 1, that's probably not a big deal if they don't care about the new fields we send them back though.

@swick
Copy link
Collaborator

swick commented Oct 20, 2025

Could even make the dbus call fail if a v2 feature is being used without setting the version field to at least 2. That way you have to opt-in to v2, and then you have a specific signature no matter what else is in the vardict.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants