-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathegmde.cpp
142 lines (124 loc) · 5.52 KB
/
egmde.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* Copyright © 2016-2022 Octopull Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Alan Griffiths <[email protected]>
*/
#include "egwallpaper.h"
#include "egwindowmanager.h"
#include "egshellcommands.h"
#include "eglauncher.h"
#include <miral/append_event_filter.h>
#include <miral/command_line_option.h>
#include <miral/display_configuration_option.h>
#include <miral/internal_client.h>
#include <miral/keymap.h>
#include <miral/runner.h>
#include <miral/set_window_management_policy.h>
#include <miral/version.h>
#include <miral/wayland_extensions.h>
#include <miral/x11_support.h>
#include <mir/fatal.h>
#include <mir/log.h>
#include <boost/filesystem.hpp>
#include <linux/input.h>
#include <csignal>
using namespace miral;
int main(int argc, char const* argv[])
{
auto const terminal_cmd = std::string{argv[0]} + "-terminal";
MirRunner runner{argc, argv};
egmde::Wallpaper wallpaper;
ExternalClientLauncher external_client_launcher;
egmde::Launcher launcher{external_client_launcher, terminal_cmd};
std::set<pid_t> shell_component_pids;
std::atomic<pid_t> shell_wofi_pid{-1};
auto run_apps = [&](std::string const& apps)
{
for (auto i = begin(apps); i != end(apps); )
{
auto const j = find(i, end(apps), ':');
shell_component_pids.insert(launcher.run_app(std::string{i, j}, egmde::Launcher::Mode::wayland));
if ((i = j) != end(apps)) ++i;
}
};
// Protocols that are "experimental" in Mir but we want to allow
auto const experimental_protocols = {"zwp_pointer_constraints_v1", "zwp_relative_pointer_manager_v1"};
WaylandExtensions extensions;
auto const supported_protocols = miral::WaylandExtensions::supported();
for (auto const& protocol : experimental_protocols)
{
if (supported_protocols.find(protocol) != end(supported_protocols))
{
extensions.enable(protocol);
}
else
{
mir::log_debug("This version of Mir doesn't support the Wayland extension %s", protocol);
}
}
// Protocols we're reserving for shell components
for (auto const& protocol : {
WaylandExtensions::zwlr_layer_shell_v1,
WaylandExtensions::zxdg_output_manager_v1,
WaylandExtensions::zwlr_foreign_toplevel_manager_v1,
WaylandExtensions::zwp_virtual_keyboard_manager_v1,
WaylandExtensions::zwp_input_method_manager_v2})
{
extensions.conditionally_enable(protocol, [&](WaylandExtensions::EnableInfo const& info)
{
return shell_component_pids.find(pid_of(info.app())) != end(shell_component_pids) ||
info.user_preference().value_or(false) || shell_wofi_pid == pid_of(info.app());
});
}
std::function<void()> launch_app = [&launcher]{ launcher.show(); };
std::function<void(mir::optional_value<std::string> const&)> const app_launcher = [&](auto& cmd) {
if (cmd.is_set())
{
launch_app = [&, cmd=cmd.value()] { shell_wofi_pid = launcher.run_app(cmd, egmde::Launcher::Mode::wayland); };
}
};
egmde::ShellCommands commands{runner, launcher, terminal_cmd, launch_app};
runner.add_stop_callback([&] { for (auto const pid : shell_component_pids) kill(pid, SIGTERM); });
runner.add_stop_callback([&] { wallpaper.stop(); });
runner.add_stop_callback([&] { launcher.stop(); });
int no_of_workspaces = 1;
auto const update_workspaces = [&](int option)
{
// clamp no_of_workspaces to [1..32]
no_of_workspaces = std::min(std::max(option, 1), 32);
};
return runner.run_with(
{
X11Support{},
extensions,
display_configuration_options,
CommandLineOption{[&](auto& option) { wallpaper.top(option);},
"wallpaper-top", "Colour of wallpaper RGB", "0x000000"},
CommandLineOption{[&](auto& option) { wallpaper.bottom(option);},
"wallpaper-bottom", "Colour of wallpaper RGB", EGMDE_WALLPAPER_BOTTOM},
pre_init(CommandLineOption{update_workspaces,
"no-of-workspaces", "Number of workspaces [1..32]", no_of_workspaces}),
external_client_launcher,
CommandLineOption{run_apps, "shell-components", "Colon separated shell components to launch on startup", ""},
CommandLineOption{app_launcher, "shell-app-launcher", "External app launcher command"},
CommandLineOption{[&](bool autostart){ if (autostart) launcher.autostart_apps(); },
"shell-enable-autostart", "Autostart apps during startup"},
StartupInternalClient{std::ref(wallpaper)},
StartupInternalClient{std::ref(launcher)},
Keymap{},
AppendEventFilter{[&](MirEvent const* e) { return commands.input_event(e); }},
set_window_management_policy<egmde::WindowManagerPolicy>(wallpaper, commands, no_of_workspaces)
});
}