mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:27:45 +00:00
BrowserSettings: Add a tab to control the Browser's autoplay settings
This adds a checkbox to enable autoplay on all websites (disabled by default) and a website list to enable autoplay on individual websites (set to file:// URLs only by default).
This commit is contained in:
parent
7966fc4780
commit
65283d6879
8 changed files with 180 additions and 6 deletions
1
Base/home/anon/.config/BrowserAutoplayAllowlist.txt
Normal file
1
Base/home/anon/.config/BrowserAutoplayAllowlist.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
file://
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AutoplaySettingsWidget.h"
|
||||||
|
#include <Applications/BrowserSettings/AutoplaySettingsWidgetGML.h>
|
||||||
|
#include <LibConfig/Client.h>
|
||||||
|
#include <LibCore/StandardPaths.h>
|
||||||
|
#include <LibGUI/Button.h>
|
||||||
|
#include <LibGUI/CheckBox.h>
|
||||||
|
#include <LibGUI/Event.h>
|
||||||
|
#include <LibGUI/InputBox.h>
|
||||||
|
#include <LibGUI/ListView.h>
|
||||||
|
#include <LibGUI/Menu.h>
|
||||||
|
|
||||||
|
static constexpr bool default_allow_autoplay_on_all_websites = false;
|
||||||
|
|
||||||
|
ErrorOr<String> AutoplayAllowlistModel::filter_list_file_path() const
|
||||||
|
{
|
||||||
|
return String::formatted("{}/BrowserAutoplayAllowlist.txt", Core::StandardPaths::config_directory());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoplayAllowlistModel::reset_default_values()
|
||||||
|
{
|
||||||
|
m_domain_list = {};
|
||||||
|
m_was_modified = true;
|
||||||
|
did_update(UpdateFlag::InvalidateAllIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<NonnullRefPtr<AutoplaySettingsWidget>> AutoplaySettingsWidget::create()
|
||||||
|
{
|
||||||
|
auto allowlist_model = TRY(try_make_ref_counted<AutoplayAllowlistModel>());
|
||||||
|
TRY(allowlist_model->load());
|
||||||
|
|
||||||
|
auto widget = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) AutoplaySettingsWidget(move(allowlist_model))));
|
||||||
|
TRY(widget->load_from_gml(autoplay_settings_widget_gml));
|
||||||
|
|
||||||
|
widget->m_allow_autoplay_on_all_websites_checkbox = widget->find_descendant_of_type_named<GUI::CheckBox>("allow_autoplay_on_all_websites_checkbox");
|
||||||
|
widget->m_allow_autoplay_on_all_websites_checkbox->set_checked(Config::read_bool("Browser"sv, "Preferences"sv, "AllowAutoplayOnAllWebsites"sv, default_allow_autoplay_on_all_websites), GUI::AllowCallback::No);
|
||||||
|
widget->m_allow_autoplay_on_all_websites_checkbox->on_checked = [widget](auto) {
|
||||||
|
widget->set_modified(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
widget->m_allowlist_view = widget->find_descendant_of_type_named<GUI::ListView>("allowlist_view");
|
||||||
|
widget->m_allowlist_view->set_model(widget->m_allowlist_model);
|
||||||
|
widget->m_allowlist_view->on_context_menu_request = [widget](GUI::ModelIndex const& index, GUI::ContextMenuEvent const& event) {
|
||||||
|
widget->m_allowlist_view->set_cursor(index, GUI::AbstractView::SelectionUpdate::Set);
|
||||||
|
widget->m_entry_context_menu->popup(event.screen_position());
|
||||||
|
};
|
||||||
|
|
||||||
|
widget->m_add_website_button = widget->find_descendant_of_type_named<GUI::Button>("add_website_button");
|
||||||
|
widget->m_add_website_button->on_click = [widget](unsigned) {
|
||||||
|
String text;
|
||||||
|
|
||||||
|
if (GUI::InputBox::show(widget->window(), text, "Website:"sv, "Add website to autoplay allowlist"sv, GUI::InputType::NonemptyText) == GUI::Dialog::ExecResult::OK) {
|
||||||
|
widget->m_allowlist_model->add_domain(text.to_deprecated_string());
|
||||||
|
widget->set_modified(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto delete_action = GUI::CommonActions::make_delete_action([widget](GUI::Action const&) {
|
||||||
|
if (!widget->m_allowlist_view->selection().is_empty()) {
|
||||||
|
widget->m_allowlist_model->delete_domain(widget->m_allowlist_view->selection().first().row());
|
||||||
|
widget->set_modified(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
widget->m_entry_context_menu = TRY(GUI::Menu::try_create());
|
||||||
|
widget->m_entry_context_menu->add_action(move(delete_action));
|
||||||
|
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoplaySettingsWidget::AutoplaySettingsWidget(NonnullRefPtr<AutoplayAllowlistModel> allowlist_model)
|
||||||
|
: m_allowlist_model(move(allowlist_model))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoplaySettingsWidget::apply_settings()
|
||||||
|
{
|
||||||
|
m_allowlist_model->save().release_value_but_fixme_should_propagate_errors();
|
||||||
|
Config::write_bool("Browser"sv, "Preferences"sv, "AllowAutoplayOnAllWebsites"sv, m_allow_autoplay_on_all_websites_checkbox->is_checked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoplaySettingsWidget::reset_default_values()
|
||||||
|
{
|
||||||
|
m_allowlist_model->reset_default_values();
|
||||||
|
m_allow_autoplay_on_all_websites_checkbox->set_checked(default_allow_autoplay_on_all_websites);
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
@GUI::Frame {
|
||||||
|
fill_with_background_color: true
|
||||||
|
layout: @GUI::VerticalBoxLayout {
|
||||||
|
margins: [8]
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::CheckBox {
|
||||||
|
name: "allow_autoplay_on_all_websites_checkbox"
|
||||||
|
text: "Allow media to automatically play on all websites"
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::GroupBox {
|
||||||
|
title: "Autoplay Allowlist"
|
||||||
|
layout: @GUI::VerticalBoxLayout {
|
||||||
|
margins: [8]
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::ListView {
|
||||||
|
name: "allowlist_view"
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Widget {
|
||||||
|
fixed_height: 32
|
||||||
|
layout: @GUI::HorizontalBoxLayout {}
|
||||||
|
|
||||||
|
@GUI::Layout::Spacer {}
|
||||||
|
|
||||||
|
@GUI::Button {
|
||||||
|
name: "add_website_button"
|
||||||
|
fixed_width: 100
|
||||||
|
text: "Add website..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ContentFilterSettingsWidget.h"
|
||||||
|
#include <AK/Error.h>
|
||||||
|
#include <AK/NonnullRefPtr.h>
|
||||||
|
#include <AK/RefPtr.h>
|
||||||
|
#include <AK/String.h>
|
||||||
|
#include <LibGUI/Forward.h>
|
||||||
|
#include <LibGUI/SettingsWindow.h>
|
||||||
|
|
||||||
|
class AutoplayAllowlistModel : public DomainListModel {
|
||||||
|
public:
|
||||||
|
virtual ErrorOr<String> filter_list_file_path() const override;
|
||||||
|
virtual void reset_default_values() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AutoplaySettingsWidget : public GUI::SettingsWindow::Tab {
|
||||||
|
C_OBJECT_ABSTRACT(AutoplaySettingsWidget)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static ErrorOr<NonnullRefPtr<AutoplaySettingsWidget>> create();
|
||||||
|
|
||||||
|
virtual void apply_settings() override;
|
||||||
|
virtual void reset_default_values() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit AutoplaySettingsWidget(NonnullRefPtr<AutoplayAllowlistModel>);
|
||||||
|
|
||||||
|
RefPtr<GUI::Menu> m_entry_context_menu;
|
||||||
|
RefPtr<GUI::CheckBox> m_allow_autoplay_on_all_websites_checkbox;
|
||||||
|
RefPtr<GUI::Button> m_add_website_button;
|
||||||
|
RefPtr<GUI::ListView> m_allowlist_view;
|
||||||
|
NonnullRefPtr<AutoplayAllowlistModel> m_allowlist_model;
|
||||||
|
};
|
|
@ -4,16 +4,19 @@ serenity_component(
|
||||||
TARGETS BrowserSettings
|
TARGETS BrowserSettings
|
||||||
)
|
)
|
||||||
|
|
||||||
|
compile_gml(AutoplaySettingsWidget.gml AutoplaySettingsWidgetGML.h autoplay_settings_widget_gml)
|
||||||
compile_gml(BrowserSettingsWidget.gml BrowserSettingsWidgetGML.h browser_settings_widget_gml)
|
compile_gml(BrowserSettingsWidget.gml BrowserSettingsWidgetGML.h browser_settings_widget_gml)
|
||||||
compile_gml(ContentFilterSettingsWidget.gml ContentFilterSettingsWidgetGML.h content_filter_settings_widget_gml)
|
compile_gml(ContentFilterSettingsWidget.gml ContentFilterSettingsWidgetGML.h content_filter_settings_widget_gml)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
|
AutoplaySettingsWidget.cpp
|
||||||
BrowserSettingsWidget.cpp
|
BrowserSettingsWidget.cpp
|
||||||
ContentFilterSettingsWidget.cpp
|
ContentFilterSettingsWidget.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(GENERATED_SOURCES
|
set(GENERATED_SOURCES
|
||||||
|
AutoplaySettingsWidgetGML.h
|
||||||
BrowserSettingsWidgetGML.h
|
BrowserSettingsWidgetGML.h
|
||||||
ContentFilterSettingsWidgetGML.h
|
ContentFilterSettingsWidgetGML.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "ContentFilterSettingsWidget.h"
|
#include "ContentFilterSettingsWidget.h"
|
||||||
|
|
||||||
#include <AK/NonnullRefPtr.h>
|
#include <AK/NonnullRefPtr.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <Applications/BrowserSettings/ContentFilterSettingsWidgetGML.h>
|
#include <Applications/BrowserSettings/ContentFilterSettingsWidgetGML.h>
|
||||||
#include <LibConfig/Client.h>
|
#include <LibConfig/Client.h>
|
||||||
#include <LibCore/StandardPaths.h>
|
#include <LibCore/StandardPaths.h>
|
||||||
|
@ -19,15 +20,15 @@
|
||||||
|
|
||||||
static constexpr bool s_default_enable_content_filtering = true;
|
static constexpr bool s_default_enable_content_filtering = true;
|
||||||
|
|
||||||
static DeprecatedString filter_list_file_path()
|
ErrorOr<String> DomainListModel::filter_list_file_path() const
|
||||||
{
|
{
|
||||||
return DeprecatedString::formatted("{}/BrowserContentFilters.txt", Core::StandardPaths::config_directory());
|
return String::formatted("{}/BrowserContentFilters.txt", Core::StandardPaths::config_directory());
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> DomainListModel::load()
|
ErrorOr<void> DomainListModel::load()
|
||||||
{
|
{
|
||||||
// FIXME: This should be somewhat shared with Browser.
|
// FIXME: This should be somewhat shared with Browser.
|
||||||
auto file = TRY(Core::File::open(filter_list_file_path(), Core::File::OpenMode::Read));
|
auto file = TRY(Core::File::open(TRY(filter_list_file_path()), Core::File::OpenMode::Read));
|
||||||
auto content_filter_list = TRY(Core::BufferedFile::create(move(file)));
|
auto content_filter_list = TRY(Core::BufferedFile::create(move(file)));
|
||||||
auto buffer = TRY(ByteBuffer::create_uninitialized(4096));
|
auto buffer = TRY(ByteBuffer::create_uninitialized(4096));
|
||||||
while (TRY(content_filter_list->can_read_line())) {
|
while (TRY(content_filter_list->can_read_line())) {
|
||||||
|
@ -49,7 +50,7 @@ ErrorOr<void> DomainListModel::save()
|
||||||
for (auto const& domain : m_domain_list)
|
for (auto const& domain : m_domain_list)
|
||||||
TRY(builder.try_appendff("{}\n", domain));
|
TRY(builder.try_appendff("{}\n", domain));
|
||||||
|
|
||||||
auto file = TRY(Core::File::open(filter_list_file_path(), Core::File::OpenMode::Write));
|
auto file = TRY(Core::File::open(TRY(filter_list_file_path()), Core::File::OpenMode::Write));
|
||||||
TRY(file->write_until_depleted(TRY(builder.to_byte_buffer()).bytes()));
|
TRY(file->write_until_depleted(TRY(builder.to_byte_buffer()).bytes()));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,10 @@
|
||||||
|
|
||||||
class DomainListModel : public GUI::Model {
|
class DomainListModel : public GUI::Model {
|
||||||
public:
|
public:
|
||||||
|
virtual ErrorOr<String> filter_list_file_path() const;
|
||||||
ErrorOr<void> load();
|
ErrorOr<void> load();
|
||||||
ErrorOr<void> save();
|
ErrorOr<void> save();
|
||||||
void reset_default_values();
|
virtual void reset_default_values();
|
||||||
|
|
||||||
virtual int row_count(GUI::ModelIndex const& = GUI::ModelIndex()) const override { return m_domain_list.size(); }
|
virtual int row_count(GUI::ModelIndex const& = GUI::ModelIndex()) const override { return m_domain_list.size(); }
|
||||||
virtual int column_count(GUI::ModelIndex const& = GUI::ModelIndex()) const override { return 1; }
|
virtual int column_count(GUI::ModelIndex const& = GUI::ModelIndex()) const override { return 1; }
|
||||||
|
@ -24,7 +25,7 @@ public:
|
||||||
void add_domain(DeprecatedString name);
|
void add_domain(DeprecatedString name);
|
||||||
void delete_domain(size_t index);
|
void delete_domain(size_t index);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
bool m_was_modified { false };
|
bool m_was_modified { false };
|
||||||
Vector<DeprecatedString> m_domain_list;
|
Vector<DeprecatedString> m_domain_list;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "AutoplaySettingsWidget.h"
|
||||||
#include "BrowserSettingsWidget.h"
|
#include "BrowserSettingsWidget.h"
|
||||||
#include "ContentFilterSettingsWidget.h"
|
#include "ContentFilterSettingsWidget.h"
|
||||||
#include <LibConfig/Client.h>
|
#include <LibConfig/Client.h>
|
||||||
|
@ -27,6 +28,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
|
|
||||||
TRY(Core::System::unveil("/res", "r"));
|
TRY(Core::System::unveil("/res", "r"));
|
||||||
TRY(Core::System::unveil("/home", "r"));
|
TRY(Core::System::unveil("/home", "r"));
|
||||||
|
TRY(Core::System::unveil("/home/anon/.config/BrowserAutoplayAllowlist.txt", "rwc"));
|
||||||
TRY(Core::System::unveil("/home/anon/.config/BrowserContentFilters.txt", "rwc"));
|
TRY(Core::System::unveil("/home/anon/.config/BrowserContentFilters.txt", "rwc"));
|
||||||
TRY(Core::System::unveil(nullptr, nullptr));
|
TRY(Core::System::unveil(nullptr, nullptr));
|
||||||
|
|
||||||
|
@ -36,6 +38,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
window->set_icon(app_icon.bitmap_for_size(16));
|
window->set_icon(app_icon.bitmap_for_size(16));
|
||||||
(void)TRY(window->add_tab<BrowserSettingsWidget>("Browser"_short_string, "browser"sv));
|
(void)TRY(window->add_tab<BrowserSettingsWidget>("Browser"_short_string, "browser"sv));
|
||||||
(void)TRY(window->add_tab<ContentFilterSettingsWidget>(TRY("Content Filtering"_string), "content-filtering"sv));
|
(void)TRY(window->add_tab<ContentFilterSettingsWidget>(TRY("Content Filtering"_string), "content-filtering"sv));
|
||||||
|
(void)TRY(window->add_tab(TRY(AutoplaySettingsWidget::create()), TRY("Autoplay"_string), "autoplay"sv));
|
||||||
window->set_active_tab(selected_tab);
|
window->set_active_tab(selected_tab);
|
||||||
|
|
||||||
window->show();
|
window->show();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue