Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass XDG_ACTIVATION_TOKEN to apps launched via launch_app_env #3703

Merged
merged 22 commits into from
Jan 28, 2025

Conversation

tarek-y-ismail
Copy link
Contributor

No description provided.

@tarek-y-ismail tarek-y-ismail self-assigned this Dec 18, 2024
Copy link
Collaborator

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drilling into the frontend implementation from the Server abstraction is placing logic in the wrong place, fragile when that implementation changes, and probably won't work.

We first need to break out the token issue & validation logic from xdg-activation so that it can meet the new requirements. (With this scenario there is no "requester" to check still has focus)

src/server/symbols.map Outdated Show resolved Hide resolved
src/server/server.cpp Outdated Show resolved Hide resolved
src/miral/launch_app.h Outdated Show resolved Hide resolved
src/server/server.cpp Outdated Show resolved Hide resolved
{
if (auto const config = self->server_config)
{
return config->the_token_authority()->issue_token({});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is better or I should add an overload with no parameters

@tarek-y-ismail tarek-y-ismail force-pushed the pass-xdg-activation-token-when-launching-apps branch from 852ccf5 to 6994bc1 Compare December 20, 2024 13:28
@tarek-y-ismail tarek-y-ismail marked this pull request as ready for review December 20, 2024 14:02
@tarek-y-ismail tarek-y-ismail requested a review from a team as a code owner December 20, 2024 14:02
Copy link
Collaborator

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a better architecture. But I've not yet looked closely enough to decide how tokens supplied via launch_app_env() will be handled by xdg-activation

src/include/server/mir/shell/token_authority.h Outdated Show resolved Hide resolved
src/server/symbols.map Show resolved Hide resolved
RAOF
RAOF previously requested changes Jan 7, 2025
Copy link
Contributor

@RAOF RAOF left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broadly, I think the TokenAuthority is kinda half way there. It's not actually an authority - code can't use it to check if a Token is valid, and that's tracked separately by XdgActivationV1. This is also why there's spooky action-at-a-distance in XdgActivationV1::invalidate_*() - you're maintaining a second list of valid tokens, mutating XdgActivationV1::pending_tokens by calling token_authority->revoke_token(...).

I think this would be simpler if:
a) The TokenAuthority was the... authority for whether a token was valid or not, and
b) Token was treated more as an opaque... token, rather than immediately decaying into a std::string and all the interfaces taking that.

src/miral/launch_app.cpp Show resolved Hide resolved
src/server/frontend_wayland/xdg_activation_v1.cpp Outdated Show resolved Hide resolved
src/server/frontend_wayland/xdg_activation_v1.cpp Outdated Show resolved Hide resolved
src/server/frontend_wayland/xdg_activation_v1.cpp Outdated Show resolved Hide resolved
src/server/frontend_wayland/xdg_activation_v1.cpp Outdated Show resolved Hide resolved
src/server/frontend_wayland/xdg_activation_v1.cpp Outdated Show resolved Hide resolved
src/server/frontend_wayland/xdg_activation_v1.cpp Outdated Show resolved Hide resolved
src/server/frontend_wayland/xdg_activation_v1.cpp Outdated Show resolved Hide resolved
src/include/server/mir/shell/token_authority.h Outdated Show resolved Hide resolved
Copy link
Contributor

@RAOF RAOF left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's cleaner. On further thought, I'm not sure we sensibly can decouple XdgActivation and the TokenAuthority further.

src/miral/launch_app.cpp Outdated Show resolved Hide resolved
@tarek-y-ismail tarek-y-ismail requested a review from RAOF January 9, 2025 08:22
github-merge-queue bot pushed a commit that referenced this pull request Jan 20, 2025
Closes #2586.

Adds a new constructor to `FloatingWindowManagerPolicy` to control focus
stealing prevention. This in a nutshell stops new windows from being
focused and raised. When used with xdg-activation-v1, this improves
security as external actors can't just steal focus by opening a new
window (in addition to the niceties xdg-activation-v1 adds to
usability).

TODO:
- [ ] ~Fix window offsetting. This is built off the position of the
focused window, so all windows after the second one open in the same
(x,y) position.~
Split off to #3695
- [ ] ~Fix windows closing in the order of opening instead of front to
back. see
#3693 (comment)
Moved to #3694
- [ ] ~Make sure Xwayland applications work properly. My focus has been
on Wayland applications so far.~
Xwayland doesn't seem to support xdg-activation at the moment?
- [x] Alt + tab predictably broken :/
Have to focus other applications before they work with alt + tab
- [x] Decorations are not pushed behind the focused window
- [ ] ~Need some way to focus applications launched via Mir
(Ctrl-Alt+t/T for example)~
Will be in its own PR (#3703)
@tarek-y-ismail
Copy link
Contributor Author

TIL that github's conflict editor merges (there's probably a rebase option that I missed)

Copy link
Collaborator

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/usr/bin/ld: unable to find version dependency `MIR_SERVER_INTERNAL_2.19'
/usr/bin/ld: duplicate version tag `MIR_SERVER_INTERNAL_2.20'
collect2: error: ld returned 1 exit status

src/server/symbols.map is ill formed

@AlanGriffiths
Copy link
Collaborator

(With the symbols.map fixed)

From Gnome:

  1. miral-app --focus-stealing-prevention true
  2. Ctrl-Alt-X to launch xterm
  3. Ctrl-Alt-Shift-T to launch gnome-terminal

Expect: gnome-terminal gets focus and raised
Actual: xterm remains on top with focus

@tarek-y-ismail tarek-y-ismail force-pushed the pass-xdg-activation-token-when-launching-apps branch from a96594e to 1d6a14f Compare January 22, 2025 10:50
@tarek-y-ismail
Copy link
Contributor Author

tarek-y-ismail commented Jan 22, 2025

Hopefully both issues should be fixed now (facepalm). I'm not very sure about the symbol stuff. I should really spend some time to understand it

I recommend testing with firefox and kgx. gnome-terminal doesn't seem to request activation.

Edit: To save you some frustration, here's a list of apps that request activation and others that don't:

Applications that request activation:

  • kgx
  • firefox
  • nautilus
  • baobab

Applications that DO NOT request activation:

  • gnome-terminal
  • qterminal
  • weston-terminal
  • bomber
  • qtcreator (seems to request activation with random tokens for dropdowns?)
  • glmark2-wayland
  • kate
  • pluma
  • audacity

Copy link
Collaborator

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the usecase the PR is intended to address:

From Gnome:

1. `miral-app --focus-stealing-prevention true`

2. `Ctrl-Alt-X` to launch `xterm`

3. `Ctrl-Alt-Shift-T` to launch `gnome-terminal`

Expect: gnome-terminal gets focus and raised
Actual: xterm remains on top with focus

Same with:

miral-app --focus-stealing-prevention true --shell-terminal-emulator=xfce4-terminal
miral-app --focus-stealing-prevention true --shell-terminal-emulator=qterminal

So it isn't just gnome-terminal being weird

@AlanGriffiths
Copy link
Collaborator

Applications that DO NOT request activation:

* gnome-terminal

gnome terminal does request activation:

[2025-01-22 11:46:17.010620] < - ERROR - > mirserver: XdgActivationV1::activate invalid token: gnome-shell/CLion/962086-6-Octopull-Framework16_TIME194122238

But that's not the token in XDG_ACTIVATION_TOKEN

@tarek-y-ismail tarek-y-ismail force-pushed the pass-xdg-activation-token-when-launching-apps branch from 4399ca1 to e4d92be Compare January 27, 2025 09:07
Copy link
Contributor

@mattkae mattkae left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A question about return types, but it is working well for me AFAICT!

src/server/frontend_wayland/xdg_activation_v1.cpp Outdated Show resolved Hide resolved
Copy link
Contributor

@mattkae mattkae left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am happy now, but I want to leave it up to @AlanGriffiths for any final thoughts and words!

Copy link
Collaborator

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More nits. But I think this does what it claims

src/server/shell/token_authority.cpp Outdated Show resolved Hide resolved
src/server/shell/token_authority.cpp Outdated Show resolved Hide resolved
src/server/shell/token_authority.cpp Outdated Show resolved Hide resolved
src/server/shell/CMakeLists.txt Outdated Show resolved Hide resolved
}

msh::TokenAuthority::TokenAuthority(std::shared_ptr<MainLoop>&& main_loop) :
main_loop{main_loop}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
main_loop{main_loop}
main_loop{std::move(main_loop)}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Borks the tests because the main loop then points to the void. Not sure why miral-app worked fine though...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then the tests are wrong:

struct TestTokenAuthority : testing::Test
{
    TestTokenAuthority() :
        clock{std::make_shared<mir::time::SteadyClock>()},
        main_loop{std::make_shared<mir::GLibMainLoop>(clock)},
        token_authority{std::forward<std::shared_ptr<mir::MainLoop>>(main_loop)},
        main_loop_thread{
            [this]()
            {
                main_loop->stop();
            },
            [this]()
            {
                main_loop->run();
            }}
    {
    }

    std::shared_ptr<mir::time::SteadyClock> clock;
    std::shared_ptr<mir::MainLoop> main_loop;
    mir::shell::TokenAuthority token_authority;
    mir::test::AutoUnblockThread main_loop_thread;
};

You use "perfect forwarding" to move from main_loop and transfer ownership. (If you made members const the compiler would know you don't want this)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

D'oh! Const correctness bites me again...

Copy link
Collaborator

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enough with the nits!

- Remove comment in `get_token_for_string` in favor of explaining things
  in `generate_token`
- Reduce scope of variables in `revoke_token` to the relevant if
  statement
- Include `token_authority.h` in `SHELL_SOURCES`
- Use seconds instead of milliseconds for token timeout since
  milliseconds weren't offering anything extra (other than the extra
  zeroes)

Co-authored-by: Alan Griffiths <[email protected]>
@tarek-y-ismail tarek-y-ismail force-pushed the pass-xdg-activation-token-when-launching-apps branch from 4d9ba32 to 94556f0 Compare January 28, 2025 15:19
@tarek-y-ismail
Copy link
Contributor Author

Had a small accident where I merged the testing PR and followed that by a force push without pulling first. Should alright now

Copy link
Collaborator

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new last nit

}

msh::TokenAuthority::TokenAuthority(std::shared_ptr<MainLoop>&& main_loop) :
main_loop{main_loop}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then the tests are wrong:

struct TestTokenAuthority : testing::Test
{
    TestTokenAuthority() :
        clock{std::make_shared<mir::time::SteadyClock>()},
        main_loop{std::make_shared<mir::GLibMainLoop>(clock)},
        token_authority{std::forward<std::shared_ptr<mir::MainLoop>>(main_loop)},
        main_loop_thread{
            [this]()
            {
                main_loop->stop();
            },
            [this]()
            {
                main_loop->run();
            }}
    {
    }

    std::shared_ptr<mir::time::SteadyClock> clock;
    std::shared_ptr<mir::MainLoop> main_loop;
    mir::shell::TokenAuthority token_authority;
    mir::test::AutoUnblockThread main_loop_thread;
};

You use "perfect forwarding" to move from main_loop and transfer ownership. (If you made members const the compiler would know you don't want this)

src/server/shell/token_authority.cpp Outdated Show resolved Hide resolved
@tarek-y-ismail tarek-y-ismail added this pull request to the merge queue Jan 28, 2025
Merged via the queue into main with commit 3a8c5a9 Jan 28, 2025
36 of 39 checks passed
@tarek-y-ismail tarek-y-ismail deleted the pass-xdg-activation-token-when-launching-apps branch January 28, 2025 19:15
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.

4 participants