diff --git a/Applications/SystemDialog/main.cpp b/Applications/SystemDialog/main.cpp index 23b523326d..7196f1ba97 100644 --- a/Applications/SystemDialog/main.cpp +++ b/Applications/SystemDialog/main.cpp @@ -24,48 +24,162 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include +#include #include #include #include #include +#include #include -#include -#include +#include +#include +#include +#include #include #include -static int run_shutdown_dialog(int argc, char** argv); +struct DialogOption { + String title; + String cmd; + bool enabled; + bool default_action; +}; + +Vector get_options() +{ + Vector options; + auto config = Core::ConfigFile::get_for_system("SystemDialog"); + for (auto title : config->groups()) { + dbg() << "title = " << title; + auto command = config->read_entry(title, "command", ""); + dbg() << "\tcommand=" << command; + auto enabled = config->read_bool_entry(title, "enabled", true); + dbg() << "\tenabled=" << enabled; + auto default_entry = config->read_bool_entry(title, "default", false); + dbg() << "\tdefault=" << default_entry; + + ASSERT(!(command == "" && enabled)); + + options.append({ title, command, enabled, default_entry }); + } + return options; +} int main(int argc, char** argv) { - if (argc != 2) { - printf("usage: SystemDialog \n"); - return 0; + Vector options; + + if (pledge("stdio shared_buffer rpath wpath cpath unix fattr exec", nullptr) < 0) { + perror("pledge"); + return 1; } - if (String(argv[1]) == "--shutdown") - return run_shutdown_dialog(argc, argv); + if (unveil("/etc/SystemDialog.ini", "rwc") < 0) { + perror("unveil"); + return 1; + } - fprintf(stderr, "Unknown argument: %s\n", argv[1]); - return 1; -} + if (unveil("/tmp", "rwc") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/res", "r") < 0) { + perror("unveil"); + return 1; + } + + if (unveil("/bin/Shell", "rx") < 0) { + perror("unveil"); + return 1; + } + + unveil(nullptr, nullptr); -int run_shutdown_dialog(int argc, char** argv) -{ GUI::Application app(argc, argv); - { - auto result = GUI::MessageBox::show("Shut down Serenity?", "Confirm Shutdown", GUI::MessageBox::Type::Warning, GUI::MessageBox::InputType::YesNo); + if (pledge("stdio shared_buffer rpath wpath cpath exec", nullptr) < 0) { + perror("pledge"); + return 1; + } - if (result == GUI::MessageBox::ExecYes) { - int rc = execl("/bin/shutdown", "/bin/shutdown", "-n", nullptr); - if (rc < 0) { - perror("execl"); - return 1; - } - ASSERT_NOT_REACHED(); + options = get_options(); + + if (pledge("stdio shared_buffer rpath exec", nullptr) < 0) { + perror("pledge"); + return 1; + } + + auto dialog = GUI::Dialog::construct(nullptr); + Gfx::Rect rect({ 0, 0, 180, 180 + ((options.size() - 3) * 16) }); + rect.center_within(GUI::Desktop::the().rect()); + dialog->set_rect(rect); + dialog->set_resizable(false); + dialog->set_title("SerenityOS"); + + auto main = GUI::Widget::construct(); + dialog->set_main_widget(main); + main->set_layout(make()); + main->layout()->set_margins({ 8, 8, 8, 8 }); + main->layout()->set_spacing(8); + main->set_fill_with_background_color(true); + + auto header = GUI::Label::construct(main.ptr()); + header->set_text("What would you like to do?"); + header->set_preferred_size(0, 16); + header->set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed); + header->set_font(Gfx::Font::default_bold_font()); + + int selected; + for (int i = 0; i < options.size(); i++) { + auto action = options[i]; + auto radio = GUI::RadioButton::construct(main); + radio->set_enabled(action.enabled); + radio->set_text(action.title); + + radio->on_checked = [&selected, i](auto) { + selected = i; + }; + + if (action.default_action) { + radio->set_checked(true); + selected = i; } + } + auto button_box = GUI::Widget::construct(main.ptr()); + button_box->set_layout(make()); + button_box->layout()->set_spacing(8); + + auto ok_button = GUI::Button::construct(button_box); + ok_button->on_click = [&](auto&) { + dialog->done(true); + }; + ok_button->set_text("OK"); + + auto cancel_button = GUI::Button::construct(button_box); + cancel_button->on_click = [&](auto&) { + dialog->done(false); + }; + cancel_button->set_text("Cancel"); + + dialog->exec(); + + if (pledge("stdio shared_buffer exec", nullptr) < 0) { + perror("pledge"); + return 1; + } + + if (!dialog->result()) return 0; + + // TODO Don't rely on the shell + auto command = options[selected].cmd.characters(); + dbg() << command; + if (execl("/bin/Shell", "/bin/Shell", "-c", command, NULL) < 0) { + perror("execl"); + return 1; } } diff --git a/Base/etc/SystemDialog.ini b/Base/etc/SystemDialog.ini new file mode 100644 index 0000000000..1e074a0b58 --- /dev/null +++ b/Base/etc/SystemDialog.ini @@ -0,0 +1,12 @@ +[Shut Down] +command=/bin/shutdown --now +default=1 + +[Reboot] +command=/bin/reboot + +[Log Out] +enabled=0 + +[Suspend] +enabled=0