Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion backend/include/backend/main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <backend/rpc_system.hpp>
#include <backend/password/password_prompter.hpp>
#include <backend/theme_finder.hpp>
#include <backend/program_options.hpp>
#include <ssh/async/processing_thread.hpp>
#include <events/app_wide_events.hpp>

Expand All @@ -24,7 +25,7 @@
class Main
{
public:
Main(int const argc, char const* const* argv);
Main(ProgramOptions options);
~Main();

Main(Main const&) = delete;
Expand Down
10 changes: 10 additions & 0 deletions backend/include/backend/program_options.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include <optional>

struct ProgramOptions
{
bool enableDevTools = false;
};

std::optional<ProgramOptions> parseProgramOptions(int argc, char const* const* argv);
9 changes: 8 additions & 1 deletion backend/source/backend/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_library(
rpc_filesystem.cpp
rpc_system.cpp
theme_finder.cpp
program_options.cpp
password/password_prompter.cpp
process/process.cpp
process/process_store.cpp
Expand Down Expand Up @@ -45,7 +46,7 @@ target_sources(
main.cpp
)

find_package(Boost CONFIG 1.86.0 REQUIRED COMPONENTS filesystem process)
find_package(Boost CONFIG 1.86.0 REQUIRED COMPONENTS filesystem process program_options)

target_include_directories(backend PUBLIC "${CMAKE_SOURCE_DIR}/backend/include")

Expand All @@ -65,6 +66,7 @@ target_link_libraries(
efsw-static
Boost::filesystem
Boost::process
Boost::program_options
roar-include-only
shared-data
utility
Expand Down Expand Up @@ -92,6 +94,9 @@ else()
set(BROWSER_ENGINE "webkitgtk")
endif()

include(ProcessorCount)
ProcessorCount(nproc)

if (NOT OMIT_FRONTEND_BUILD)
# Creates a target that is compiled through emscripten. This target becomes the frontend part.
nui_add_emscripten_target(
Expand Down Expand Up @@ -119,6 +124,8 @@ if (NOT OMIT_FRONTEND_BUILD)
# -DXML_TO_NUI_TOOL=$<TARGET_FILE:xml-to-nui>
-DOFFLINE_BUILD=${OFFLINE_BUILD}
-DBACKEND_BUILD_TYPE=${BACKEND_BUILD_TYPE}
BUILD_OPTIONS
-- -j${nproc}
)

target_sources(
Expand Down
73 changes: 71 additions & 2 deletions backend/source/backend/linux/main_linux.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,75 @@
// Nothing yet

#include <backend/linux/main_linux.hpp>
#include <gtk/gtk.h>

Main::PlatformSpecifics::PlatformSpecifics(Nui::Window&, Nui::RpcHub&)
{}
#if GTK_MAJOR_VERSION >= 4
# include <jsc/jsc.h>
# include <webkit/webkit.h>
# ifdef GDK_WINDOWING_X11
# include <gdk/x11/gdkx.h>
# endif
#elif GTK_MAJOR_VERSION >= 3
# include <JavaScriptCore/JavaScript.h>
# include <webkit2/webkit2.h>
#endif

namespace
{
bool isFilteredAction(WebKitContextMenuAction action)
{
switch (action)
{
case WEBKIT_CONTEXT_MENU_ACTION_RELOAD:
case WEBKIT_CONTEXT_MENU_ACTION_GO_BACK:
case WEBKIT_CONTEXT_MENU_ACTION_GO_FORWARD:
case WEBKIT_CONTEXT_MENU_ACTION_STOP:
return true;
default:
return false;
}
}
}

gboolean on_context_menu(
WebKitWebView* /*web_view*/,
WebKitContextMenu* context_menu,
GdkEvent* /*event*/,
WebKitHitTestResult* /*hit_test_result*/,
gpointer /*user_data*/
)
{
GList* items = webkit_context_menu_get_items(context_menu);
GList* copy = g_list_copy(items);
for (GList* l = copy; l != NULL; l = l->next)
{
auto* item = static_cast<WebKitContextMenuItem*>(l->data);
if (isFilteredAction(webkit_context_menu_item_get_stock_action(item)))
webkit_context_menu_remove(context_menu, item);
}
g_list_free(copy);
return FALSE; // show modified menu
}

Main::PlatformSpecifics::PlatformSpecifics(Nui::Window& wnd, Nui::RpcHub&)
{
auto* webview = static_cast<GtkWidget*>(wnd.getNativeWebView());
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
g_signal_connect(
webview,
"context-menu",
G_CALLBACK(
+[](WebKitWebView* web_view,
WebKitContextMenu* context_menu,
GdkEvent* event,
WebKitHitTestResult* hit_test_result,
gpointer user_data) -> gboolean
{
return on_context_menu(web_view, context_menu, event, hit_test_result, user_data);
}
),
nullptr
);
#pragma clang diagnostic pop
}
11 changes: 8 additions & 3 deletions backend/source/backend/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#endif

#include <backend/process/process_store.hpp>
#include <backend/program_options.hpp>
#include <utility/resources.hpp>
#include <roar/filesystem/special_paths.hpp>

Expand Down Expand Up @@ -174,7 +175,7 @@ Main::LoggerSetup::LoggerSetup(Persistence::StateHolder& stateHolder)
);
}

Main::Main(int const, char const* const*)
Main::Main(ProgramOptions options)
: shuttingDown_{false}
, programDir_{boost::dll::program_location().parent_path().string()}
, stateHolder_{programDir_}
Expand All @@ -183,7 +184,7 @@ Main::Main(int const, char const* const*)
Nui::WindowOptions{
.title = "NuiSftp"s,
#ifdef NDEBUG
.debug = false,
.debug = options.enableDevTools,
#else
.debug = true,
#endif
Expand Down Expand Up @@ -346,6 +347,10 @@ void Main::startChildSignalTimer()

int main(int const argc, char const* const* argv)
{
auto options = parseProgramOptions(argc, argv);
if (!options)
return 0;

#ifdef __linux__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wc99-designator"
Expand Down Expand Up @@ -380,7 +385,7 @@ int main(int const argc, char const* const* argv)
ssh_init();

{
Main m{argc, argv};
Main m{std::move(*options)};
m.startChildSignalTimer();
m.show();
}
Expand Down
37 changes: 37 additions & 0 deletions backend/source/backend/program_options.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <backend/program_options.hpp>

#include <boost/program_options.hpp>

#include <iostream>

std::optional<ProgramOptions> parseProgramOptions(int argc, char const* const* argv)
{
try
{
boost::program_options::options_description desc("Allowed options");
desc.add_options()("help", "produce help message")(
"enable-dev-tools", "Enable developer tools (DevTools in Browser)"
);

boost::program_options::variables_map vm;
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
boost::program_options::notify(vm);

if (vm.count("help"))
{
std::cout << desc << "\n";
return std::nullopt;
}

ProgramOptions options;
if (vm.count("enable-dev-tools"))
options.enableDevTools = true;

return options;
}
catch (std::exception& e)
{
std::cerr << "Error parsing program options: " << e.what() << "\n";
return std::nullopt;
}
}
38 changes: 18 additions & 20 deletions backend/source/backend/theme_finder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,32 @@ ThemeFinder::ThemeFinder(std::filesystem::path const& relativeRoot, AppWideEvent
events.onReloadThemes,
[&events, relativeRoot](bool)
{
Log::info("Reloading themes... relativeRoot='{}'", relativeRoot.generic_string());
events.availableThemes = findAvailableThemes(relativeRoot);
Log::info("availableThemes updated, count={}", events.availableThemes.value().size());
events.availableThemes.eventContext().sync();
Log::info("availableThemes sync done.");
}
)}
{}
{
Log::info("ThemeFinder constructed with relativeRoot='{}'", relativeRoot.generic_string());
}

std::vector<std::filesystem::path> ThemeFinder::findAvailableThemes(std::filesystem::path const& relativeRoot)
{
const auto dirs = getThemeDirs(relativeRoot);
std::vector<std::filesystem::path> themes{};
Log::info("Finding available themes in {} candidate directories.", dirs.size());
for (const auto& dir : dirs)
{
Log::info("Checking theme directory: {}", dir.generic_string());
if (!std::filesystem::exists(dir) || !std::filesystem::is_directory(dir))
{
Log::info("Skipping non-existing or non-directory theme path: {}", dir.generic_string());
continue;
}
Log::info("findAvailableThemes called with relativeRoot='{}'", relativeRoot.generic_string());
std::error_code ec;
const bool rootExists = std::filesystem::exists(relativeRoot, ec);
Log::info("relativeRoot exists={}, ec='{}'", rootExists, ec.message());

for (const auto& entry : std::filesystem::directory_iterator(dir))
{
if (entry.is_regular_file() && entry.path().extension() == ".css")
{
Log::info("Found theme file: {}", entry.path().generic_string());
themes.push_back(entry.path().stem());
}
}
const auto files = findFilesInSearchPaths(relativeRoot, "themes/*.css");
Log::info("findFilesInSearchPaths returned {} file(s).", files.size());
std::vector<std::filesystem::path> themes;
themes.reserve(files.size());
for (const auto& file : files)
{
Log::info("Found theme file: '{}', stem='{}'", file.generic_string(), file.stem().generic_string());
themes.push_back(file.stem());
}
Log::info("Theme discovery complete, found {} themes.", themes.size());
return themes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,10 @@ class ComboSetting : public Setting<Disengageable, ValueType>
.onOpen = [this]()
{
if (doLoad_)
{
Log::info("ComboSetting doing load on open.");
return doLoad_();
}
return false;
},
.dontUpdateValue = true,
Expand Down
24 changes: 24 additions & 0 deletions frontend/source/frontend/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ static std::unique_ptr<ThemeController> themeController{};
static std::unique_ptr<MainPage> mainPage{};
static std::unique_ptr<Nui::Dom::Dom> dom{};

namespace
{
void printKeys(Nui::val obj)
{
Nui::val keys = Nui::val::global("Object").call<Nui::val>("keys", obj);
int length = keys["length"].as<int>();
for (int i = 0; i < length; ++i)
{
std::string key = keys[i].as<std::string>();
Log::debug("Key: '{}'", key);
}
}
}

bool tryLoad(std::shared_ptr<Nui::TimerHandle> const& setupWait)
{
static int counter = 0;
Expand Down Expand Up @@ -85,6 +99,16 @@ bool tryLoad(std::shared_ptr<Nui::TimerHandle> const& setupWait)

Log::info("Calling setup completion function");
mainPage->onSetupComplete();

Log::debug("Dumping nui_rpc.backend and nui_rpc.frontend for debugging:");
auto nuiRpc = Nui::val::global("nui_rpc");
if (!nuiRpc.isUndefined() && nuiRpc.hasOwnProperty("backend"))
{
Log::debug("nui_rpc.backend:");
printKeys(nuiRpc["backend"]);
Log::debug("nui_rpc.frontend:");
printKeys(nuiRpc["frontend"]);
}
}
catch (std::exception const& exc)
{
Expand Down
5 changes: 0 additions & 5 deletions persistence/include/persistence/state_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,6 @@ namespace Persistence
{
if constexpr (CanCallUseDefaultsFrom<std::decay_t<decltype(toFill.*memAccessor.pointer)>>)
{
Log::debug(
"Calling useDefaultsFrom for member {} of type {}.",
memAccessor.name,
typeid(decltype(toFill.*memAccessor.pointer)).name()
);
useDefaultsFrom(toFill.*memAccessor.pointer, defaultsFromThis.*memAccessor.pointer);
}
else
Expand Down
Loading