6
6
* SPDX-License-Identifier: BSD-2-Clause
7
7
*/
8
8
9
+ #include < AK/Enumerate.h>
9
10
#include < Applications/Browser/Browser.h>
10
11
#include < Applications/Browser/BrowserWindow.h>
11
12
#include < Applications/Browser/Tab.h>
23
24
#include < LibGUI/TabWidget.h>
24
25
#include < LibMain/Main.h>
25
26
#include < LibWeb/Loader/ResourceLoader.h>
27
+ #include < LibWebView/ChromeProcess.h>
26
28
#include < LibWebView/CookieJar.h>
27
29
#include < LibWebView/Database.h>
28
30
#include < LibWebView/OutOfProcessWebView.h>
@@ -88,24 +90,60 @@ static ErrorOr<void> load_autoplay_allowlist()
88
90
return {};
89
91
}
90
92
93
+ enum class NewWindow {
94
+ No,
95
+ Yes,
96
+ };
97
+
98
+ static Vector<URL::URL> sanitize_urls (Vector<ByteString> const & raw_urls, NewWindow new_window = NewWindow::Yes)
99
+ {
100
+ Vector<URL::URL> sanitized_urls;
101
+ for (auto const & raw_url : raw_urls) {
102
+ if (auto url = WebView::sanitize_url (raw_url); url.has_value ())
103
+ sanitized_urls.append (url.release_value ());
104
+ }
105
+
106
+ if (sanitized_urls.is_empty ())
107
+ sanitized_urls.append (new_window == NewWindow::Yes ? Browser::g_home_url : Browser::g_new_tab_url);
108
+
109
+ return sanitized_urls;
110
+ }
111
+
112
+ static void open_urls_from_client (Browser::BrowserWindow& window, Vector<ByteString> const & raw_urls, NewWindow new_window)
113
+ {
114
+ auto urls = sanitize_urls (raw_urls, new_window);
115
+
116
+ for (auto [i, url] : enumerate(urls)) {
117
+ if (new_window == NewWindow::Yes)
118
+ outln (" New browser windows are not yet supported. Opening URLs in a new tab." );
119
+
120
+ auto activate_tab = i == 0 ? Web::HTML::ActivateTab::Yes : Web::HTML::ActivateTab::No;
121
+ window.create_new_tab (url, activate_tab);
122
+ }
123
+
124
+ window.show ();
125
+ }
126
+
91
127
ErrorOr<int > serenity_main (Main::Arguments arguments)
92
128
{
93
129
if (getuid () == 0 ) {
94
130
warnln (" Refusing to run as root" );
95
131
return 1 ;
96
132
}
97
133
98
- TRY (Core::System::pledge (" sigaction stdio recvfd sendfd unix fattr cpath rpath wpath proc exec" ));
134
+ TRY (Core::System::pledge (" sigaction stdio recvfd sendfd accept unix fattr cpath rpath wpath proc exec" ));
99
135
100
136
WebView::ProcessManager::initialize ();
101
137
102
- TRY (Core::System::pledge (" stdio recvfd sendfd unix fattr cpath rpath wpath proc exec" ));
138
+ TRY (Core::System::pledge (" stdio recvfd sendfd accept unix fattr cpath rpath wpath proc exec" ));
103
139
104
- Vector<StringView> specified_urls;
140
+ Vector<ByteString> specified_urls;
141
+ bool new_window = false ;
105
142
106
143
Core::ArgsParser args_parser;
107
144
args_parser.add_positional_argument (specified_urls, " URLs to open" , " url" , Core::ArgsParser::Required::No);
108
145
args_parser.add_option (Browser::g_webdriver_content_ipc_path, " Path to WebDriver IPC for WebContent" , " webdriver-content-path" , 0 , " path" , Core::ArgsParser::OptionHideMode::CommandLineAndMarkdown);
146
+ args_parser.add_option (new_window, " Force opening in a new window" , " new-window" , ' n' );
109
147
110
148
args_parser.parse (arguments);
111
149
@@ -122,6 +160,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
122
160
TRY (Desktop::Launcher::add_allowed_handler_with_only_specific_urls (" /bin/Help" , { URL::create_with_file_scheme (man_file) }));
123
161
TRY (Desktop::Launcher::seal_allowlist ());
124
162
163
+ TRY (Core::System::unveil (" /tmp/session/%sid/Ladybird.pid" , " rwc" ));
164
+ TRY (Core::System::unveil (" /tmp/session/%sid/Ladybird.socket" , " rwc" ));
125
165
TRY (Core::System::unveil (" /tmp/session/%sid/portal/filesystemaccess" , " rw" ));
126
166
TRY (Core::System::unveil (" /tmp/session/%sid/portal/filesystemaccess" , " rw" ));
127
167
TRY (Core::System::unveil (" /tmp/session/%sid/portal/image" , " rw" ));
@@ -140,6 +180,12 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
140
180
TRY (Core::System::unveil (" /bin/Browser" , " x" ));
141
181
TRY (Core::System::unveil (nullptr , nullptr ));
142
182
183
+ WebView::ChromeProcess chrome_process;
184
+ if (TRY (chrome_process.connect (specified_urls, new_window)) == WebView::ChromeProcess::ProcessDisposition::ExitProcess) {
185
+ outln (" Opening in existing process" );
186
+ return 0 ;
187
+ }
188
+
143
189
Web::ResourceLoader::initialize (TRY (WebView::RequestServerAdapter::try_create ()));
144
190
145
191
auto app_icon = GUI::Icon::default_icon (" app-browser" sv);
@@ -170,18 +216,16 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
170
216
}
171
217
}
172
218
173
- Vector<URL::URL> initial_urls;
174
-
175
- for (auto specified_url : specified_urls) {
176
- if (auto url = WebView::sanitize_url (specified_url); url.has_value ())
177
- initial_urls.append (url.release_value ());
178
- }
219
+ auto cookie_jar = TRY (WebView::CookieJar::create (*database));
220
+ auto window = Browser::BrowserWindow::construct (cookie_jar, sanitize_urls (specified_urls), man_file);
179
221
180
- if (initial_urls.is_empty ())
181
- initial_urls.append (Browser::g_home_url);
222
+ chrome_process.on_new_tab = [&](auto const & raw_urls) {
223
+ open_urls_from_client (*window, raw_urls, NewWindow::No);
224
+ };
182
225
183
- auto cookie_jar = TRY (WebView::CookieJar::create (*database));
184
- auto window = Browser::BrowserWindow::construct (cookie_jar, initial_urls, man_file);
226
+ chrome_process.on_new_window = [&](auto const & raw_urls) {
227
+ open_urls_from_client (*window, raw_urls, NewWindow::Yes);
228
+ };
185
229
186
230
auto content_filters_watcher = TRY (Core::FileWatcher::create ());
187
231
content_filters_watcher->on_change = [&](Core::FileWatcherEvent const &) {
0 commit comments