Skip to content

Commit

Permalink
Pass XDG_ACTIVATION_TOKEN and DESKTOP_STARTUP_ID to launched apps
Browse files Browse the repository at this point in the history
Refactored the parameters of `launch_app_env` to use `std::optional`
instead of `mir::optional_value`
  • Loading branch information
tarek-y-ismail committed Jan 23, 2025
1 parent 96f53bd commit d63b6e3
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 58 deletions.
4 changes: 2 additions & 2 deletions src/include/server/mir/frontend/connector.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
#ifndef MIR_FRONTEND_CONNECTOR_H_
#define MIR_FRONTEND_CONNECTOR_H_

#include <mir/optional_value.h>
#include <functional>
#include <memory>
#include <optional>
#include <string>

namespace mir
Expand All @@ -41,7 +41,7 @@ class Connector

virtual int client_socket_fd(std::function<void(std::shared_ptr<scene::Session> const& session)> const& connect_handler) const = 0;

virtual auto socket_name() const -> optional_value<std::string> = 0;
virtual auto socket_name() const -> std::optional<std::string> = 0;

protected:
Connector() = default;
Expand Down
6 changes: 3 additions & 3 deletions src/include/server/mir/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
#define MIR_SERVER_H_

#include "mir/shell/window_manager_builder.h"
#include "mir/optional_value.h"
#include "mir_toolkit/common.h"

#include <functional>
#include <memory>
#include <optional>
#include <vector>

struct wl_display;
Expand Down Expand Up @@ -471,10 +471,10 @@ class Server
std::function<bool(std::shared_ptr<scene::Session> const&, char const*)> const& extension_filter);

/// Get the name of the Wayland endpoint (if any) usable as a $WAYLAND_DISPLAY value
auto wayland_display() const -> optional_value<std::string>;
auto wayland_display() const -> std::optional<std::string>;

/// Get the name of the X11 display usable as a $DISPLAY value
auto x11_display() const -> optional_value<std::string>;
auto x11_display() const -> std::optional<std::string>;

auto get_activation_token() const -> std::string;

Expand Down
7 changes: 5 additions & 2 deletions src/miral/external_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <mir/options/option.h>
#include <mir/server.h>
#include <mir/log.h>

#include <algorithm>
#include <stdexcept>
Expand Down Expand Up @@ -117,8 +118,9 @@ auto miral::ExternalClientLauncher::launch(std::vector<std::string> const& comma

auto const wayland_display = self->server->wayland_display();
auto const x11_display = self->server->x11_display();
auto const activation_token = self->server->get_activation_token();

return launch_app_env(command_line, wayland_display, x11_display, self->env);
return launch_app_env(command_line, wayland_display, x11_display, activation_token, self->env);
}

miral::ExternalClientLauncher::ExternalClientLauncher() : self{std::make_shared<Self>()} {}
Expand All @@ -133,7 +135,8 @@ auto miral::ExternalClientLauncher::launch_using_x11(std::vector<std::string> c
if (auto const x11_display = self->server->x11_display())
{
auto const wayland_display = self->server->wayland_display();
return launch_app_env(command_line, wayland_display, x11_display, self->x11_env);
return launch_app_env(
command_line, wayland_display, x11_display, self->server->get_activation_token(), self->x11_env);
}

return -1;
Expand Down
68 changes: 33 additions & 35 deletions src/miral/launch_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@

#include <boost/throw_exception.hpp>

#include <string>
#include <unistd.h>
#include <signal.h>

#include <cstring>
#include <stdexcept>
#include <system_error>
#include <vector>

Expand Down Expand Up @@ -93,46 +93,21 @@ auto Environment::exec_env() const & -> std::vector<char const*>
result.push_back(nullptr);
return result;
}
} // namespace

auto miral::launch_app_env(
std::vector<std::string> const& app,
mir::optional_value<std::string> const& wayland_display,
mir::optional_value<std::string> const& x11_display,
miral::AppEnvironment const& app_env) -> pid_t
void assign_or_unset(Environment& env, std::string const& key, auto optional_value)
{
Environment application_environment;

for (auto const& [key, value]: app_env)
{
if (value)
{
application_environment.setenv(key, value.value());
}
else
{
application_environment.unsetenv(key);
}
}

if (wayland_display)
if (optional_value)
{
application_environment.setenv("WAYLAND_DISPLAY", wayland_display.value()); // configure Wayland socket
env.setenv(key, optional_value.value());
}
else
{
application_environment.unsetenv("WAYLAND_DISPLAY");
}

if (x11_display)
{
application_environment.setenv("DISPLAY", x11_display.value()); // configure X11 socket
}
else
{
application_environment.unsetenv("DISPLAY");
env.unsetenv(key);
}
}

auto execute_with_environment(std::vector<std::string> const app, Environment& application_environment) -> pid_t
{
auto const exec_env = application_environment.exec_env();

std::vector<char const*> exec_args;
Expand All @@ -155,12 +130,35 @@ auto miral::launch_app_env(
sigfillset(&all_signals);
pthread_sigmask(SIG_UNBLOCK, &all_signals, nullptr);

// execvpe() isn't listed as being async-signal-safe, but the implementation looks fine and rewriting seems unnecessary
execvpe(exec_args[0], const_cast<char*const*>(exec_args.data()), const_cast<char*const*>(exec_env.data()));
// execvpe() isn't listed as being async-signal-safe, but the implementation looks fine and rewriting seems
// unnecessary
execvpe(exec_args[0], const_cast<char* const*>(exec_args.data()), const_cast<char* const*>(exec_env.data()));

mir::log_warning("Failed to execute client (\"%s\") error: %s", exec_args[0], strerror(errno));
exit(EXIT_FAILURE);
}

return pid;
}
} // namespace


auto miral::launch_app_env(
std::vector<std::string> const& app,
std::optional<std::string> const& wayland_display,
std::optional<std::string> const& x11_display,
std::optional<std::string> const& xdg_activation_token,
miral::AppEnvironment const& app_env) -> pid_t
{
Environment application_environment;

for (auto const& [key, value]: app_env)
assign_or_unset(application_environment, key, value);

assign_or_unset(application_environment, "WAYLAND_DISPLAY", wayland_display); // configure Wayland socket
assign_or_unset(application_environment, "DISPLAY", x11_display); // configure X11 socket
assign_or_unset(application_environment, "XDG_ACTIVATION_TOKEN", xdg_activation_token);
assign_or_unset(application_environment, "DESKTOP_STARTUP_ID", xdg_activation_token);

return execute_with_environment(app, application_environment);
}
5 changes: 3 additions & 2 deletions src/miral/launch_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ namespace miral
using AppEnvironment = std::map<std::string, std::optional<std::string>>;

auto launch_app_env(std::vector<std::string> const& app,
mir::optional_value<std::string> const& wayland_display,
mir::optional_value<std::string> const& x11_display,
std::optional<std::string> const& wayland_display,
std::optional<std::string> const& x11_display,
std::optional<std::string> const& xdg_activation_token,
AppEnvironment const& app_env) -> pid_t;
}

Expand Down
14 changes: 12 additions & 2 deletions src/miral/runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,23 @@ auto miral::MirRunner::display_config_file() const -> std::string
return self->display_config_file;
}

namespace
{
auto optional_to_mir_optional(std::optional<std::string> const& opt) -> mir::optional_value<std::string>
{
if (!opt)
return {};
return mir::optional_value{*opt};
}
}

auto miral::MirRunner::wayland_display() const -> mir::optional_value<std::string>
{
std::lock_guard lock{self->mutex};

if (auto const server = self->weak_server.lock())
{
return server->wayland_display();
return optional_to_mir_optional(server->wayland_display());
}

return {};
Expand All @@ -292,7 +302,7 @@ auto miral::MirRunner::x11_display() const -> mir::optional_value<std::string>

if (auto const server = self->weak_server.lock())
{
return server->x11_display();
return optional_to_mir_optional(server->x11_display());
}

return {};
Expand Down
1 change: 1 addition & 0 deletions src/miral/x11_support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <mir/options/configuration.h>
#include <mir/main_loop.h>
#include <mir/fd.h>
#include <mir/fatal.h>

namespace mo = mir::options;

Expand Down
3 changes: 2 additions & 1 deletion src/server/frontend_wayland/wayland_connector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "mir/graphics/graphic_buffer_allocator.h"
#include "mir/frontend/wayland.h"

#include <optional>
#include <sys/eventfd.h>
#include <sys/stat.h>
#include <sys/socket.h>
Expand Down Expand Up @@ -525,7 +526,7 @@ void mf::WaylandConnector::on_surface_created(
compositor_global->on_surface_created(client, id, callback);
}

auto mf::WaylandConnector::socket_name() const -> optional_value<std::string>
auto mf::WaylandConnector::socket_name() const -> std::optional<std::string>
{
return wayland_display;
}
Expand Down
2 changes: 1 addition & 1 deletion src/server/frontend_wayland/wayland_connector.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class WaylandConnector : public Connector
/// Callback is never called if a wl_surface with the id is never created
void on_surface_created(wl_client* client, uint32_t id, std::function<void(WlSurface*)> const& callback);

auto socket_name() const -> optional_value<std::string> override;
auto socket_name() const -> std::optional<std::string> override;

auto get_extension(std::string const& name) const -> std::shared_ptr<void>;

Expand Down
4 changes: 2 additions & 2 deletions src/server/frontend_xwayland/xwayland_connector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ int mf::XWaylandConnector::client_socket_fd(
return -1;
}

auto mf::XWaylandConnector::socket_name() const -> optional_value<std::string>
auto mf::XWaylandConnector::socket_name() const -> std::optional<std::string>
{
std::lock_guard lock{mutex};

Expand All @@ -111,7 +111,7 @@ auto mf::XWaylandConnector::socket_name() const -> optional_value<std::string>
}
else
{
return optional_value<std::string>();
return std::nullopt;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/server/frontend_xwayland/xwayland_connector.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class XWaylandConnector : public Connector, public std::enable_shared_from_this<
int client_socket_fd(
std::function<void(std::shared_ptr<scene::Session> const& session)> const& connect_handler) const override;

auto socket_name() const -> optional_value<std::string> override;
auto socket_name() const -> std::optional<std::string> override;

private:
std::shared_ptr<Executor> const main_loop;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include <boost/lexical_cast.hpp>

#include <optional>
#include <string>
#include <cstdlib>

Expand Down Expand Up @@ -53,9 +54,9 @@ struct NullConnector : mf::Connector
return -1;
}

mir::optional_value<std::string> socket_name() const override
std::optional<std::string> socket_name() const override
{
return mir::optional_value<std::string>();
return std::optional<std::string>();
}
};
}
Expand Down
8 changes: 3 additions & 5 deletions src/server/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,8 @@
#include "mir/renderer/renderer_factory.h"

#include "frontend_wayland/wayland_connector.h"

#include <iostream>
#include <mir/server.h>

#include <optional>

namespace mo = mir::options;
namespace mi = mir::input;
Expand Down Expand Up @@ -465,15 +463,15 @@ auto mir::Server::open_wayland_client_socket() -> Fd
BOOST_THROW_EXCEPTION(std::logic_error("Cannot open connection when not running"));
}

auto mir::Server::wayland_display() const -> optional_value<std::string>
auto mir::Server::wayland_display() const -> std::optional<std::string>
{
if (auto const config = self->server_config)
return config->the_wayland_connector()->socket_name();

BOOST_THROW_EXCEPTION(std::logic_error("Cannot open connection when not running"));
}

auto mir::Server::x11_display() const -> mir::optional_value<std::string>
auto mir::Server::x11_display() const -> std::optional<std::string>
{
if (auto const config = self->server_config)
return config->the_xwayland_connector()->socket_name();
Expand Down

0 comments on commit d63b6e3

Please sign in to comment.