1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-22 06:32:11 +00:00

Taskbar: Support arbitrary executables as QuickLaunch entries

This commit is contained in:
Maciej 2021-12-29 17:06:14 +01:00 committed by Andreas Kling
parent 2e8e959896
commit 3022baddc2
2 changed files with 51 additions and 4 deletions

View file

@ -5,13 +5,18 @@
*/ */
#include "QuickLaunchWidget.h" #include "QuickLaunchWidget.h"
#include "LibCore/IODevice.h"
#include <AK/LexicalPath.h>
#include <LibConfig/Client.h> #include <LibConfig/Client.h>
#include <LibCore/MimeData.h> #include <LibCore/MimeData.h>
#include <LibCore/Process.h>
#include <LibCore/System.h> #include <LibCore/System.h>
#include <LibGUI/BoxLayout.h> #include <LibGUI/BoxLayout.h>
#include <LibGUI/FileIconProvider.h>
#include <LibGUI/Menu.h> #include <LibGUI/Menu.h>
#include <LibGUI/MessageBox.h> #include <LibGUI/MessageBox.h>
#include <serenity.h> #include <serenity.h>
#include <sys/stat.h>
namespace Taskbar { namespace Taskbar {
@ -39,6 +44,24 @@ ErrorOr<void> QuickLaunchEntryAppFile::launch() const
return {}; return {};
} }
ErrorOr<void> QuickLaunchEntryExecutable::launch() const
{
auto pid = Core::Process::spawn(m_path);
if (pid < 0)
return Error::from_syscall("Core::Process::spawn", -errno);
return {};
}
GUI::Icon QuickLaunchEntryExecutable::icon() const
{
return GUI::FileIconProvider::icon_for_executable(m_path);
}
String QuickLaunchEntryExecutable::name() const
{
return LexicalPath { m_path }.basename();
}
QuickLaunchWidget::QuickLaunchWidget() QuickLaunchWidget::QuickLaunchWidget()
{ {
set_shrink_to_fit(true); set_shrink_to_fit(true);
@ -73,17 +96,26 @@ QuickLaunchWidget::~QuickLaunchWidget()
OwnPtr<QuickLaunchEntry> QuickLaunchEntry::create_from_config_value(StringView value) OwnPtr<QuickLaunchEntry> QuickLaunchEntry::create_from_config_value(StringView value)
{ {
if (value.ends_with(".af")) { if (!value.starts_with("/") && value.ends_with(".af")) {
auto af_path = String::formatted("{}/{}", Desktop::AppFile::APP_FILES_DIRECTORY, value); auto af_path = String::formatted("{}/{}", Desktop::AppFile::APP_FILES_DIRECTORY, value);
return make<QuickLaunchEntryAppFile>(Desktop::AppFile::open(af_path)); return make<QuickLaunchEntryAppFile>(Desktop::AppFile::open(af_path));
} } else
return {}; return create_from_path(value);
} }
OwnPtr<QuickLaunchEntry> QuickLaunchEntry::create_from_path(StringView path) OwnPtr<QuickLaunchEntry> QuickLaunchEntry::create_from_path(StringView path)
{ {
if (path.ends_with(".af")) if (path.ends_with(".af"))
return make<QuickLaunchEntryAppFile>(Desktop::AppFile::open(path)); return make<QuickLaunchEntryAppFile>(Desktop::AppFile::open(path));
auto stat_or_error = Core::System::stat(path);
if (stat_or_error.is_error()) {
dbgln("Failed to stat quick launch entry file: {}", stat_or_error.release_error());
return {};
}
auto stat = stat_or_error.release_value();
if (stat.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
return make<QuickLaunchEntryExecutable>(path);
dbgln("Config value {} is not a valid quick launch entry", path);
return {}; return {};
} }
@ -140,7 +172,7 @@ void QuickLaunchWidget::drop_event(GUI::DropEvent& event)
if (entry) { if (entry) {
auto item_name = entry->name().replace(" ", "", true); auto item_name = entry->name().replace(" ", "", true);
add_or_adjust_button(item_name, entry.release_nonnull()); add_or_adjust_button(item_name, entry.release_nonnull());
Config::write_string("Taskbar", quick_launch, item_name, url.basename()); Config::write_string("Taskbar", quick_launch, item_name, url.path());
} }
} }
} }

View file

@ -39,6 +39,21 @@ private:
NonnullRefPtr<Desktop::AppFile> m_app_file; NonnullRefPtr<Desktop::AppFile> m_app_file;
}; };
class QuickLaunchEntryExecutable : public QuickLaunchEntry {
public:
explicit QuickLaunchEntryExecutable(String path)
: m_path(move(path))
{
}
virtual ErrorOr<void> launch() const override;
virtual GUI::Icon icon() const override;
virtual String name() const override;
private:
String m_path;
};
class QuickLaunchWidget : public GUI::Frame class QuickLaunchWidget : public GUI::Frame
, public Config::Listener { , public Config::Listener {
C_OBJECT(QuickLaunchWidget); C_OBJECT(QuickLaunchWidget);