mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-10-11 20:58:16 +03:00
Taskbar: Abstract out quick launch entries
... into QuickLaunchEntry class. It will be used to implement adding plain executables to the taskbar. For now, it adds TRY() error handling to app launching :^)
This commit is contained in:
parent
ccb8374434
commit
2e8e959896
Notes:
sideshowbarker
2024-07-17 20:32:51 +09:00
Author: https://github.com/sppmacd Commit: https://github.com/SerenityOS/serenity/commit/2e8e959896a Pull-request: https://github.com/SerenityOS/serenity/pull/11488 Reviewed-by: https://github.com/awesomekling
@ -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 (!app_file->is_valid())
|
||||
return;
|
||||
auto button = find_child_of_type_named<GUI::Button>(button_name);
|
||||
if (!button) {
|
||||
button = &add<GUI::Button>();
|
||||
if (value.ends_with(".af")) {
|
||||
auto af_path = String::formatted("{}/{}", Desktop::AppFile::APP_FILES_DIRECTORY, value);
|
||||
return make<QuickLaunchEntryAppFile>(Desktop::AppFile::open(af_path));
|
||||
}
|
||||
auto app_executable = app_file->executable();
|
||||
auto app_run_in_terminal = app_file->run_in_terminal();
|
||||
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)
|
||||
{
|
||||
auto button = find_child_of_type_named<GUI::Button>(button_name);
|
||||
if (!button)
|
||||
button = &add<GUI::Button>();
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user