summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Services/Taskbar/QuickLaunchWidget.cpp101
-rw-r--r--Userland/Services/Taskbar/QuickLaunchWidget.h28
2 files changed, 89 insertions, 40 deletions
diff --git a/Userland/Services/Taskbar/QuickLaunchWidget.cpp b/Userland/Services/Taskbar/QuickLaunchWidget.cpp
index f968a27786..f18685b86f 100644
--- a/Userland/Services/Taskbar/QuickLaunchWidget.cpp
+++ b/Userland/Services/Taskbar/QuickLaunchWidget.cpp
@@ -7,8 +7,10 @@
#include "QuickLaunchWidget.h"
#include <LibConfig/Client.h>
#include <LibCore/MimeData.h>
+#include <LibCore/System.h>
#include <LibGUI/BoxLayout.h>
#include <LibGUI/Menu.h>
+#include <LibGUI/MessageBox.h>
#include <serenity.h>
namespace Taskbar {
@@ -16,6 +18,27 @@ namespace Taskbar {
constexpr auto quick_launch = "QuickLaunch"sv;
constexpr int quick_launch_button_size = 24;
+ErrorOr<void> QuickLaunchEntryAppFile::launch() const
+{
+ auto executable = m_app_file->executable();
+
+ pid_t pid = TRY(Core::System::fork());
+ if (pid == 0) {
+ if (chdir(Core::StandardPaths::home_directory().characters()) < 0) {
+ perror("chdir");
+ exit(1);
+ }
+ if (m_app_file->run_in_terminal())
+ execl("/bin/Terminal", "Terminal", "-e", executable.characters(), nullptr);
+ else
+ execl(executable.characters(), executable.characters(), nullptr);
+ perror("execl");
+ VERIFY_NOT_REACHED();
+ } else
+ TRY(Core::System::disown(pid));
+ return {};
+}
+
QuickLaunchWidget::QuickLaunchWidget()
{
set_shrink_to_fit(true);
@@ -36,10 +59,11 @@ QuickLaunchWidget::QuickLaunchWidget()
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);
+ auto value = Config::read_string("Taskbar", quick_launch, name);
+ auto entry = QuickLaunchEntry::create_from_config_value(value);
+ if (!entry)
+ continue;
+ add_or_adjust_button(name, entry.release_nonnull());
}
}
@@ -47,40 +71,38 @@ QuickLaunchWidget::~QuickLaunchWidget()
{
}
-void QuickLaunchWidget::add_or_adjust_button(String const& button_name, NonnullRefPtr<Desktop::AppFile> app_file)
+OwnPtr<QuickLaunchEntry> QuickLaunchEntry::create_from_config_value(StringView value)
+{
+ if (value.ends_with(".af")) {
+ auto af_path = String::formatted("{}/{}", Desktop::AppFile::APP_FILES_DIRECTORY, value);
+ return make<QuickLaunchEntryAppFile>(Desktop::AppFile::open(af_path));
+ }
+ return {};
+}
+
+OwnPtr<QuickLaunchEntry> QuickLaunchEntry::create_from_path(StringView path)
+{
+ if (path.ends_with(".af"))
+ return make<QuickLaunchEntryAppFile>(Desktop::AppFile::open(path));
+ return {};
+}
+
+void QuickLaunchWidget::add_or_adjust_button(String const& button_name, NonnullOwnPtr<QuickLaunchEntry>&& entry)
{
- if (!app_file->is_valid())
- return;
auto button = find_child_of_type_named<GUI::Button>(button_name);
- if (!button) {
+ if (!button)
button = &add<GUI::Button>();
- }
- 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());
+ auto icon = entry->icon();
+ button->set_icon(icon.bitmap_for_size(16));
+ button->set_tooltip(entry->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");
- }
+ button->on_click = [entry = move(entry), this](auto) {
+ auto result = entry->launch();
+ if (result.is_error())
+ GUI::MessageBox::show_error(window(), String::formatted("Failed to open quick launch entry: {}", result.release_error()));
};
button->on_context_menu_request = [this, button_name](auto& context_menu_event) {
m_context_menu_app_name = button_name;
@@ -100,9 +122,10 @@ void QuickLaunchWidget::config_key_was_removed(String const& domain, String cons
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);
+ auto entry = QuickLaunchEntry::create_from_config_value(value);
+ if (!entry)
+ return;
+ add_or_adjust_button(key, entry.release_nonnull());
}
}
@@ -113,10 +136,10 @@ void QuickLaunchWidget::drop_event(GUI::DropEvent& event)
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);
+ auto entry = QuickLaunchEntry::create_from_path(url.path());
+ if (entry) {
+ auto item_name = entry->name().replace(" ", "", true);
+ add_or_adjust_button(item_name, entry.release_nonnull());
Config::write_string("Taskbar", quick_launch, item_name, url.basename());
}
}
diff --git a/Userland/Services/Taskbar/QuickLaunchWidget.h b/Userland/Services/Taskbar/QuickLaunchWidget.h
index 6f90c67c2f..fccecf88d9 100644
--- a/Userland/Services/Taskbar/QuickLaunchWidget.h
+++ b/Userland/Services/Taskbar/QuickLaunchWidget.h
@@ -13,6 +13,32 @@
namespace Taskbar {
+class QuickLaunchEntry {
+public:
+ virtual ~QuickLaunchEntry() = default;
+ virtual ErrorOr<void> launch() const = 0;
+ virtual GUI::Icon icon() const = 0;
+ virtual String name() const = 0;
+
+ static OwnPtr<QuickLaunchEntry> create_from_config_value(StringView path);
+ static OwnPtr<QuickLaunchEntry> create_from_path(StringView path);
+};
+
+class QuickLaunchEntryAppFile : public QuickLaunchEntry {
+public:
+ explicit QuickLaunchEntryAppFile(NonnullRefPtr<Desktop::AppFile> file)
+ : m_app_file(move(file))
+ {
+ }
+
+ virtual ErrorOr<void> launch() const override;
+ virtual GUI::Icon icon() const override { return m_app_file->icon(); }
+ virtual String name() const override { return m_app_file->name(); }
+
+private:
+ NonnullRefPtr<Desktop::AppFile> m_app_file;
+};
+
class QuickLaunchWidget : public GUI::Frame
, public Config::Listener {
C_OBJECT(QuickLaunchWidget);
@@ -27,7 +53,7 @@ public:
private:
QuickLaunchWidget();
- void add_or_adjust_button(String const&, NonnullRefPtr<Desktop::AppFile>);
+ void add_or_adjust_button(String const&, NonnullOwnPtr<QuickLaunchEntry>&&);
RefPtr<GUI::Menu> m_context_menu;
RefPtr<GUI::Action> m_context_menu_default_action;
String m_context_menu_app_name;