Serenity Operating System
at master 164 lines 7.1 kB view raw
1/* 2 * Copyright (c) 2019-2020, Jesse Buhagiar <jooster669@gmail.com> 3 * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org> 4 * Copyright (c) 2022, the SerenityOS developers. 5 * 6 * SPDX-License-Identifier: BSD-2-Clause 7 */ 8 9#include "BackgroundSettingsWidget.h" 10#include <AK/StringBuilder.h> 11#include <Applications/DisplaySettings/BackgroundSettingsGML.h> 12#include <LibConfig/Client.h> 13#include <LibCore/ConfigFile.h> 14#include <LibDesktop/Launcher.h> 15#include <LibGUI/Application.h> 16#include <LibGUI/BoxLayout.h> 17#include <LibGUI/Button.h> 18#include <LibGUI/Clipboard.h> 19#include <LibGUI/ComboBox.h> 20#include <LibGUI/ConnectionToWindowServer.h> 21#include <LibGUI/Desktop.h> 22#include <LibGUI/FilePicker.h> 23#include <LibGUI/FileSystemModel.h> 24#include <LibGUI/FileTypeFilter.h> 25#include <LibGUI/IconView.h> 26#include <LibGUI/ItemListModel.h> 27#include <LibGUI/MessageBox.h> 28#include <LibGfx/Palette.h> 29#include <LibGfx/SystemTheme.h> 30 31namespace DisplaySettings { 32 33BackgroundSettingsWidget::BackgroundSettingsWidget(bool& background_settings_changed) 34 : m_background_settings_changed { background_settings_changed } 35{ 36 m_modes.append("Tile"); 37 m_modes.append("Center"); 38 m_modes.append("Stretch"); 39 40 create_frame(); 41 load_current_settings(); 42} 43 44void BackgroundSettingsWidget::create_frame() 45{ 46 load_from_gml(background_settings_gml).release_value_but_fixme_should_propagate_errors(); 47 48 m_monitor_widget = *find_descendant_of_type_named<DisplaySettings::MonitorWidget>("monitor_widget"); 49 50 m_wallpaper_view = *find_descendant_of_type_named<GUI::IconView>("wallpaper_view"); 51 m_wallpaper_view->set_model(GUI::FileSystemModel::create("/res/wallpapers")); 52 m_wallpaper_view->set_model_column(GUI::FileSystemModel::Column::Name); 53 m_wallpaper_view->on_selection_change = [this] { 54 DeprecatedString path; 55 if (m_wallpaper_view->selection().is_empty()) { 56 path = ""; 57 } else { 58 auto index = m_wallpaper_view->selection().first(); 59 path = static_cast<GUI::FileSystemModel*>(m_wallpaper_view->model())->full_path(index); 60 } 61 62 m_monitor_widget->set_wallpaper(path); 63 set_modified(true); 64 }; 65 66 m_context_menu = GUI::Menu::construct(); 67 m_show_in_file_manager_action = GUI::Action::create("Show in File Manager", Gfx::Bitmap::load_from_file("/res/icons/16x16/app-file-manager.png"sv).release_value_but_fixme_should_propagate_errors(), [this](GUI::Action const&) { 68 LexicalPath path { m_monitor_widget->wallpaper() }; 69 Desktop::Launcher::open(URL::create_with_file_scheme(path.dirname(), path.basename())); 70 }); 71 m_context_menu->add_action(*m_show_in_file_manager_action); 72 73 m_context_menu->add_separator(); 74 m_copy_action = GUI::CommonActions::make_copy_action( 75 [this](auto&) { 76 auto url = URL::create_with_file_scheme(m_monitor_widget->wallpaper()).to_deprecated_string(); 77 GUI::Clipboard::the().set_data(url.bytes(), "text/uri-list"); 78 }, 79 this); 80 m_context_menu->add_action(*m_copy_action); 81 82 m_wallpaper_view->on_context_menu_request = [&](const GUI::ModelIndex& index, const GUI::ContextMenuEvent& event) { 83 if (index.is_valid()) { 84 m_context_menu->popup(event.screen_position(), m_show_in_file_manager_action); 85 } 86 }; 87 88 auto& button = *find_descendant_of_type_named<GUI::Button>("wallpaper_open_button"); 89 button.on_click = [this](auto) { 90 auto path = GUI::FilePicker::get_open_filepath(window(), "Select wallpaper from file system", "/res/wallpapers"sv, false, GUI::Dialog::ScreenPosition::CenterWithinParent, { { GUI::FileTypeFilter::image_files(), GUI::FileTypeFilter::all_files() } }); 91 if (!path.has_value()) 92 return; 93 m_wallpaper_view->selection().clear(); 94 m_monitor_widget->set_wallpaper(path.value()); 95 m_background_settings_changed = true; 96 set_modified(true); 97 }; 98 99 m_mode_combo = *find_descendant_of_type_named<GUI::ComboBox>("mode_combo"); 100 m_mode_combo->set_only_allow_values_from_model(true); 101 m_mode_combo->set_model(*GUI::ItemListModel<DeprecatedString>::create(m_modes)); 102 bool first_mode_change = true; 103 m_mode_combo->on_change = [this, first_mode_change](auto&, const GUI::ModelIndex& index) mutable { 104 m_monitor_widget->set_wallpaper_mode(m_modes.at(index.row())); 105 m_background_settings_changed = !first_mode_change; 106 first_mode_change = false; 107 set_modified(true); 108 }; 109 110 m_color_input = *find_descendant_of_type_named<GUI::ColorInput>("color_input"); 111 m_color_input->set_color_has_alpha_channel(false); 112 m_color_input->set_color_picker_title("Select color for desktop"); 113 bool first_color_change = true; 114 m_color_input->on_change = [this, first_color_change]() mutable { 115 m_monitor_widget->set_background_color(m_color_input->color()); 116 m_background_settings_changed = !first_color_change; 117 first_color_change = false; 118 set_modified(true); 119 }; 120} 121 122void BackgroundSettingsWidget::load_current_settings() 123{ 124 auto ws_config = Core::ConfigFile::open("/etc/WindowServer.ini").release_value_but_fixme_should_propagate_errors(); 125 126 auto selected_wallpaper = Config::read_string("WindowManager"sv, "Background"sv, "Wallpaper"sv, ""sv); 127 if (!selected_wallpaper.is_empty()) { 128 auto index = static_cast<GUI::FileSystemModel*>(m_wallpaper_view->model())->index(selected_wallpaper, m_wallpaper_view->model_column()); 129 m_wallpaper_view->set_cursor(index, GUI::AbstractView::SelectionUpdate::Set); 130 m_monitor_widget->set_wallpaper(selected_wallpaper); 131 } 132 133 auto mode = ws_config->read_entry("Background", "Mode", "Center"); 134 if (!m_modes.contains_slow(mode)) { 135 warnln("Invalid background mode '{}' in WindowServer config, falling back to 'Center'", mode); 136 mode = "Center"; 137 } 138 m_monitor_widget->set_wallpaper_mode(mode); 139 m_mode_combo->set_selected_index(m_modes.find_first_index(mode).value_or(0), GUI::AllowCallback::No); 140 141 auto palette_desktop_color = palette().desktop_background(); 142 auto background_color = ws_config->read_entry("Background", "Color", ""); 143 144 if (!background_color.is_empty()) { 145 auto opt_color = Color::from_string(background_color); 146 if (opt_color.has_value()) 147 palette_desktop_color = opt_color.value(); 148 } 149 150 m_color_input->set_color(palette_desktop_color, GUI::AllowCallback::No); 151 m_monitor_widget->set_background_color(palette_desktop_color); 152 m_background_settings_changed = false; 153} 154 155void BackgroundSettingsWidget::apply_settings() 156{ 157 if (!GUI::Desktop::the().set_wallpaper(m_monitor_widget->wallpaper_bitmap(), m_monitor_widget->wallpaper())) 158 GUI::MessageBox::show_error(window(), DeprecatedString::formatted("Unable to load file {} as wallpaper", m_monitor_widget->wallpaper())); 159 160 GUI::Desktop::the().set_background_color(m_color_input->text()); 161 GUI::Desktop::the().set_wallpaper_mode(m_monitor_widget->wallpaper_mode()); 162} 163 164}