From c74afdde26d4cbb8e158e2da6cf6c6f091e3eb3f Mon Sep 17 00:00:00 2001 From: faxe1008 Date: Thu, 18 Nov 2021 19:43:16 +0100 Subject: [PATCH] Taskbar: Add dropping of AppFiles to QuickLaunch This change adds the capability to drop AppFiles to the quick launch section of the Taskbar. All logic was moved to a new QuickLaunchWidget. --- Userland/Services/Taskbar/CMakeLists.txt | 1 + .../Services/Taskbar/QuickLaunchWidget.cpp | 111 ++++++++++++++++++ Userland/Services/Taskbar/QuickLaunchWidget.h | 33 ++++++ Userland/Services/Taskbar/TaskbarWindow.cpp | 88 +------------- Userland/Services/Taskbar/TaskbarWindow.h | 8 +- 5 files changed, 148 insertions(+), 93 deletions(-) create mode 100644 Userland/Services/Taskbar/QuickLaunchWidget.cpp create mode 100644 Userland/Services/Taskbar/QuickLaunchWidget.h diff --git a/Userland/Services/Taskbar/CMakeLists.txt b/Userland/Services/Taskbar/CMakeLists.txt index b8c6d2293b..08420cb444 100644 --- a/Userland/Services/Taskbar/CMakeLists.txt +++ b/Userland/Services/Taskbar/CMakeLists.txt @@ -7,6 +7,7 @@ serenity_component( set(SOURCES main.cpp ClockWidget.cpp + QuickLaunchWidget.cpp ShutdownDialog.cpp TaskbarButton.cpp TaskbarWindow.cpp diff --git a/Userland/Services/Taskbar/QuickLaunchWidget.cpp b/Userland/Services/Taskbar/QuickLaunchWidget.cpp new file mode 100644 index 0000000000..b74e9ff551 --- /dev/null +++ b/Userland/Services/Taskbar/QuickLaunchWidget.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2021, Fabian Blatz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "QuickLaunchWidget.h" +#include +#include +#include +#include + +namespace Taskbar { + +constexpr auto quick_launch = "QuickLaunch"sv; +constexpr int quick_launch_button_size = 24; + +QuickLaunchWidget::QuickLaunchWidget() +{ + set_shrink_to_fit(true); + set_layout(); + layout()->set_spacing(0); + set_frame_thickness(0); + set_fixed_height(24); + + auto keys = Config::list_keys("Taskbar", quick_launch); + for (auto& name : keys) { + auto af_name = Config::read_string("Taskbar", quick_launch, name); + auto af_path = String::formatted("{}/{}", Desktop::AppFile::APP_FILES_DIRECTORY, af_name); + auto af = Desktop::AppFile::open(af_path); + add_or_adjust_button(name, af); + } +} + +QuickLaunchWidget::~QuickLaunchWidget() +{ +} + +void QuickLaunchWidget::add_or_adjust_button(String const& button_name, NonnullRefPtr app_file) +{ + if (!app_file->is_valid()) + return; + auto button = find_child_of_type_named(button_name); + if (!button) { + button = &add(); + } + auto app_executable = app_file->executable(); + auto app_run_in_terminal = app_file->run_in_terminal(); + button->set_fixed_size(quick_launch_button_size, quick_launch_button_size); + button->set_button_style(Gfx::ButtonStyle::Coolbar); + button->set_icon(app_file->icon().bitmap_for_size(16)); + button->set_tooltip(app_file->name()); + button->set_name(button_name); + button->on_click = [app_executable, app_run_in_terminal](auto) { + pid_t pid = fork(); + if (pid < 0) { + perror("fork"); + } else if (pid == 0) { + if (chdir(Core::StandardPaths::home_directory().characters()) < 0) { + perror("chdir"); + exit(1); + } + if (app_run_in_terminal) + execl("/bin/Terminal", "Terminal", "-e", app_executable.characters(), nullptr); + else + execl(app_executable.characters(), app_executable.characters(), nullptr); + perror("execl"); + VERIFY_NOT_REACHED(); + } else { + if (disown(pid) < 0) + perror("disown"); + } + }; +} + +void QuickLaunchWidget::config_key_was_removed(String const& domain, String const& group, String const& key) +{ + if (domain == "Taskbar" && group == quick_launch) { + auto button = find_child_of_type_named(key); + if (button) + remove_child(*button); + } +} + +void QuickLaunchWidget::config_string_did_change(String const& domain, String const& group, String const& key, String const& value) +{ + if (domain == "Taskbar" && group == quick_launch) { + auto af_path = String::formatted("{}/{}", Desktop::AppFile::APP_FILES_DIRECTORY, value); + auto af = Desktop::AppFile::open(af_path); + add_or_adjust_button(key, af); + } +} + +void QuickLaunchWidget::drop_event(GUI::DropEvent& event) +{ + event.accept(); + + if (event.mime_data().has_urls()) { + auto urls = event.mime_data().urls(); + for (auto& url : urls) { + auto af = Desktop::AppFile::open(url.path()); + if (af->is_valid()) { + auto item_name = af->name().replace(" ", "", true); + add_or_adjust_button(item_name, af); + Config::write_string("Taskbar", quick_launch, item_name, url.basename()); + } + } + } +} + +} diff --git a/Userland/Services/Taskbar/QuickLaunchWidget.h b/Userland/Services/Taskbar/QuickLaunchWidget.h new file mode 100644 index 0000000000..9e444ca4b1 --- /dev/null +++ b/Userland/Services/Taskbar/QuickLaunchWidget.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021, Fabian Blatz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace Taskbar { + +class QuickLaunchWidget : public GUI::Frame + , public Config::Listener { + C_OBJECT(QuickLaunchWidget); + +public: + virtual ~QuickLaunchWidget() override; + + virtual void config_key_was_removed(String const&, String const&, String const&) override; + virtual void config_string_did_change(String const&, String const&, String const&, String const&) override; + + virtual void drop_event(GUI::DropEvent&); + +private: + QuickLaunchWidget(); + void add_or_adjust_button(String const&, NonnullRefPtr); +}; + +} diff --git a/Userland/Services/Taskbar/TaskbarWindow.cpp b/Userland/Services/Taskbar/TaskbarWindow.cpp index 071db6ee18..02279520b2 100644 --- a/Userland/Services/Taskbar/TaskbarWindow.cpp +++ b/Userland/Services/Taskbar/TaskbarWindow.cpp @@ -7,9 +7,9 @@ #include "TaskbarWindow.h" #include "ClockWidget.h" +#include "QuickLaunchWidget.h" #include "TaskbarButton.h" #include -#include #include #include #include @@ -26,9 +26,6 @@ #include #include -constexpr const char* quick_launch = "QuickLaunch"; -constexpr int quick_launch_button_size = 24; - class TaskbarWidget final : public GUI::Widget { C_OBJECT(TaskbarWidget); @@ -75,7 +72,7 @@ TaskbarWindow::TaskbarWindow(NonnullRefPtr start_menu) m_start_button->set_menu(m_start_menu); main_widget.add_child(*m_start_button); - create_quick_launch_bar(); + main_widget.add(); m_task_button_container = main_widget.add(); m_task_button_container->set_layout(); @@ -111,87 +108,6 @@ void TaskbarWindow::show_desktop_button_clicked(unsigned) GUI::WindowManagerServerConnection::the().async_toggle_show_desktop(); } -void TaskbarWindow::config_key_was_removed(String const& domain, String const& group, String const& key) -{ - if (domain == "Taskbar" && group == quick_launch) { - auto button = m_quick_launch_bar->find_child_of_type_named(key); - if (button) - m_quick_launch_bar->remove_child(*button); - } -} - -void TaskbarWindow::config_string_did_change(String const& domain, String const& group, String const& key, String const& value) -{ - if (domain == "Taskbar" && group == quick_launch) { - auto af_path = String::formatted("{}/{}", Desktop::AppFile::APP_FILES_DIRECTORY, value); - auto af = Desktop::AppFile::open(af_path); - if (!af->is_valid()) - return; - - auto button = m_quick_launch_bar->find_child_of_type_named(key); - if (button) { - set_quick_launch_button_data(*button, key, af); - } else { - auto& new_button = m_quick_launch_bar->add(); - set_quick_launch_button_data(new_button, key, af); - } - } -} - -void TaskbarWindow::create_quick_launch_bar() -{ - m_quick_launch_bar = main_widget()->add(); - m_quick_launch_bar->set_shrink_to_fit(true); - m_quick_launch_bar->set_layout(); - m_quick_launch_bar->layout()->set_spacing(0); - m_quick_launch_bar->set_frame_thickness(0); - - auto config = Core::ConfigFile::open_for_app("Taskbar"); - - // FIXME: Core::ConfigFile does not keep the order of the entries. - for (auto& name : config->keys(quick_launch)) { - auto af_name = config->read_entry(quick_launch, name); - auto af_path = String::formatted("{}/{}", Desktop::AppFile::APP_FILES_DIRECTORY, af_name); - auto af = Desktop::AppFile::open(af_path); - if (!af->is_valid()) - continue; - auto& button = m_quick_launch_bar->add(); - set_quick_launch_button_data(button, name, af); - } - m_quick_launch_bar->set_fixed_height(24); -} - -void TaskbarWindow::set_quick_launch_button_data(GUI::Button& button, String const& button_name, NonnullRefPtr app_file) -{ - auto app_executable = app_file->executable(); - auto app_run_in_terminal = app_file->run_in_terminal(); - button.set_fixed_size(quick_launch_button_size, quick_launch_button_size); - button.set_button_style(Gfx::ButtonStyle::Coolbar); - button.set_icon(app_file->icon().bitmap_for_size(16)); - button.set_tooltip(app_file->name()); - button.set_name(button_name); - button.on_click = [app_executable, app_run_in_terminal](auto) { - pid_t pid = fork(); - if (pid < 0) { - perror("fork"); - } else if (pid == 0) { - if (chdir(Core::StandardPaths::home_directory().characters()) < 0) { - perror("chdir"); - exit(1); - } - if (app_run_in_terminal) - execl("/bin/Terminal", "Terminal", "-e", app_executable.characters(), nullptr); - else - execl(app_executable.characters(), app_executable.characters(), nullptr); - perror("execl"); - VERIFY_NOT_REACHED(); - } else { - if (disown(pid) < 0) - perror("disown"); - } - }; -} - void TaskbarWindow::on_screen_rects_change(const Vector& rects, size_t main_screen_index) { const auto& rect = rects[main_screen_index]; diff --git a/Userland/Services/Taskbar/TaskbarWindow.h b/Userland/Services/Taskbar/TaskbarWindow.h index dd71950453..395d375903 100644 --- a/Userland/Services/Taskbar/TaskbarWindow.h +++ b/Userland/Services/Taskbar/TaskbarWindow.h @@ -14,8 +14,7 @@ #include #include -class TaskbarWindow final : public GUI::Window - , public Config::Listener { +class TaskbarWindow final : public GUI::Window { C_OBJECT(TaskbarWindow); public: @@ -24,13 +23,9 @@ public: static int taskbar_height() { return 27; } static int taskbar_icon_size() { return 16; } - virtual void config_key_was_removed(String const&, String const&, String const&) override; - virtual void config_string_did_change(String const&, String const&, String const&, String const&) override; - private: explicit TaskbarWindow(NonnullRefPtr start_menu); static void show_desktop_button_clicked(unsigned); - void create_quick_launch_bar(); void set_quick_launch_button_data(GUI::Button&, String const&, NonnullRefPtr); void on_screen_rects_change(const Vector&, size_t); NonnullRefPtr create_button(const WindowIdentifier&); @@ -53,7 +48,6 @@ private: NonnullRefPtr m_start_menu; RefPtr m_task_button_container; RefPtr m_default_icon; - RefPtr m_quick_launch_bar; Gfx::IntSize m_applet_area_size; RefPtr m_applet_area_container;