Merge branch '10-save-restore-window-state' into 'master'
Resolve "Save & restore window state" Closes #10 See merge request libreweb/browser!9master
commit
02978f7565
16
README.md
16
README.md
|
@ -8,7 +8,7 @@ What would you do different; if you could **reinvent** The Internet in 21st cent
|
|||
|
||||
I was inspired by Douglas Engelbart, Tim Berners-Lee and Ted Nelson as well as projects like IPFS, Jekyll, ARPANET, and more.
|
||||
|
||||
*Note:* Project is still in Alpha phase!
|
||||
*Note:* Project is still in development!
|
||||
|
||||
## Download
|
||||
|
||||
|
@ -19,6 +19,10 @@ I was inspired by Douglas Engelbart, Tim Berners-Lee and Ted Nelson as well as p
|
|||
![Browser Screenshot](./misc/browser_screenshot.png)
|
||||
![Browser Markdown Editor](./misc/browser_screenshot_2.png)
|
||||
|
||||
## Documentation
|
||||
|
||||
Visit the [dedicated documentation site](https://docs.libreweb.org) for user documentation.
|
||||
|
||||
## Ideas/Features
|
||||
|
||||
The current success criteria:
|
||||
|
@ -40,11 +44,11 @@ The current success criteria:
|
|||
|
||||
## Developers
|
||||
|
||||
Decentralized Browser written in C++20 with C libraries. And using the [cmark-gfm](https://github.com/github/cmark-gfm) library, used for CommonMark (markdown) parsing.
|
||||
Decentralized Browser is written C++ together with some [libraries](/lib). It's using the [cmark-gfm](https://github.com/github/cmark-gfm) library for example, which is used for CommonMark (markdown) parsing.
|
||||
|
||||
Browser is using GTK 3 as UI library including Pango & Cairo for text drawing and manipulation.
|
||||
We're using markdown as the source-code of the content/site. No HTML and JavaScript anymore, content is king after all.
|
||||
|
||||
For now we will use markdown as the source of the site. No HTML and JavaScript anymore, content is king after all.
|
||||
LibreWeb Browser is using [Gnome GTK3](https://developer.gnome.org/gtk3/stable/) as UI framework.
|
||||
|
||||
### Development Environment
|
||||
|
||||
|
@ -57,10 +61,10 @@ For the build you need at least:
|
|||
* GCC 9 or higher (GCC 8 should also work, but not adviced. Package: `build-essential`)
|
||||
* CMake (Package: `cmake`)
|
||||
* Ninja build system (Package: `ninja-build`)
|
||||
* GTK & Cairo & Pango (including C++ bindings):
|
||||
* GTK & Pango (including C++ bindings):
|
||||
* Package: `libgtkmm-3.0-dev` under Debian based distros
|
||||
|
||||
### Documentation
|
||||
### Developer Docs
|
||||
|
||||
See latest [Developer Docs](https://gitlab.melroy.org/libreweb/browser/-/jobs/artifacts/master/file/build/docs/html/index.html?job=doxygen).
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
|
||||
# Example: https://github.com/MariaDB/server/tree/10.5/cmake
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LibreWeb Browser - Decentralized Web-Browser")
|
||||
set(CPACK_PACKAGE_VENDOR "Melroy van den Berg")
|
||||
set(CPACK_PACKAGE_CONTACT "Melroy van den Berg <info@libreweb.org>")
|
||||
set(CPACK_PACKAGE_HOMEPAGE_URL "https://libreweb.org")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/misc/package_desc.txt")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_TARGET}-${CPACK_PACKAGE_VERSION}")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "web")
|
||||
set(CPACK_RPM_PACKAGE_GROUP "Applications/Internet")
|
||||
set(CPACK_RPM_PACKAGE_GROUP "Applications/Internet")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-v${CPACK_PACKAGE_VERSION}") # Without '-Linux' suffix
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND EXISTS "/etc/os-release")
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
LibreWeb Browser is a fully decentralized free software and open-source Web Browser.
|
||||
Allowing users to easily browse and host new content on the decentralized web. Build on top of IPFS.
|
||||
|
||||
Decentralization comes with many benefits like resilient to censorship and no single point of failure.
|
||||
|
||||
I was inspired by Douglas Engelbart, Tim Berners-Lee and Ted Nelson as well as projects like IPFS, Jekyll and ARPANET.
|
||||
|
||||
Please read the documentation at https://docs.libreweb.org.
|
|
@ -2,10 +2,13 @@
|
|||
# By: Melroy van den Berg
|
||||
# Description: Release production build + create Debian package file (.deb),
|
||||
# RPM [Red Hat] Package Manager (.rpm) and compressed file (.tgz/.tar.gz)
|
||||
#
|
||||
# Installs into /usr folder (prefix)
|
||||
|
||||
rm -rf build_prod
|
||||
mkdir build_prod
|
||||
cd build_prod
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake -GNinja -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_BUILD_TYPE=Release ..
|
||||
ninja &&
|
||||
echo "INFO: Building packages...";
|
||||
cpack -G "TGZ;DEB;RPM"
|
||||
|
|
|
@ -18,11 +18,11 @@ set(PROJECT_TARGET libreweb-browser)
|
|||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
|
||||
# Find required dependencies
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(GTKMM gtkmm-3.0)
|
||||
pkg_check_modules(CAIRO cairomm-1.0)
|
||||
pkg_check_modules(GTKMM REQUIRED gtkmm-3.0)
|
||||
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
||||
|
||||
add_definitions(${GTKMM_CFLAGS_OTHER})
|
||||
|
||||
|
@ -39,8 +39,39 @@ if(NOT json_POPULATED)
|
|||
add_subdirectory(${json_SOURCE_DIR} ${json_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
# Generate Project version header file
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/project_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/project_config.h)
|
||||
|
||||
# Find the GLib path for schema installation
|
||||
execute_process(
|
||||
COMMAND
|
||||
${PKG_CONFIG_EXECUTABLE}
|
||||
glib-2.0
|
||||
--variable prefix
|
||||
OUTPUT_VARIABLE
|
||||
_glib_prefix
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
set(GSETTINGS_DIR "${_glib_prefix}/share/glib-2.0/schemas/" CACHE INTERNAL "")
|
||||
|
||||
# Fetch path for schema compiler from pkg-config
|
||||
execute_process(
|
||||
COMMAND
|
||||
${PKG_CONFIG_EXECUTABLE}
|
||||
gio-2.0
|
||||
--variable
|
||||
glib_compile_schemas
|
||||
OUTPUT_VARIABLE
|
||||
_glib_compile_schemas
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Set glib schema compiler command
|
||||
set(glib_schema_compiler ${_glib_compile_schemas} CACHE INTERNAL "")
|
||||
|
||||
set(SCHEMA_FILE ${CMAKE_CURRENT_SOURCE_DIR}/org.libreweb.browser.gschema.xml)
|
||||
|
||||
# Source code
|
||||
set(HEADERS
|
||||
about.h
|
||||
file.h
|
||||
|
@ -51,7 +82,6 @@ set(HEADERS
|
|||
draw.h
|
||||
source-code-dialog.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
main.cc
|
||||
about.cc
|
||||
|
@ -67,6 +97,21 @@ set(SOURCES
|
|||
|
||||
add_executable(${PROJECT_TARGET} ${SOURCES})
|
||||
|
||||
# Copy gschema.xml file to build directory
|
||||
set(SCHEMA_DIR ${CMAKE_CURRENT_BINARY_DIR}/gsettings)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_TARGET} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${SCHEMA_FILE}
|
||||
${SCHEMA_DIR}/org.libreweb.browser.gschema.xml
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_TARGET} POST_BUILD
|
||||
COMMAND ${glib_schema_compiler} ${SCHEMA_DIR}
|
||||
COMMENT "Compiling schemas in folder: ${SCHEMA_DIR}"
|
||||
)
|
||||
|
||||
# Add fallback for std filesystem in older GCC versions
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.4)
|
||||
|
@ -88,15 +133,18 @@ target_include_directories(${PROJECT_TARGET} PRIVATE
|
|||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_EXTENSIONS_BINARY_DIR}
|
||||
${GTKMM_INCLUDE_DIRS}
|
||||
${CAIRO_INCLUDE_DIRS}
|
||||
${PROJECT_SOURCE_DIR}/lib/ipfs-http-client/include
|
||||
)
|
||||
)
|
||||
|
||||
target_link_directories(${PROJECT_TARGET} PRIVATE
|
||||
${GTKMM_LIBRARY_DIRS}
|
||||
${CAIRO_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_TARGET} PRIVATE LibCommonMarker LibCommonMarkerExtensions ipfs-http-client Threads::Threads ${CXX_FILESYSTEM_LIBRARIES} ${GTKMM_LIBRARIES} ${CAIRO_LIBRARIES} nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(${PROJECT_TARGET} PRIVATE LibCommonMarker LibCommonMarkerExtensions ipfs-http-client Threads::Threads ${CXX_FILESYSTEM_LIBRARIES} ${GTKMM_LIBRARIES} nlohmann_json::nlohmann_json)
|
||||
|
||||
install(TARGETS ${PROJECT_TARGET} RUNTIME DESTINATION "bin" COMPONENT applications)
|
||||
# Install browser binary
|
||||
install(TARGETS ${PROJECT_TARGET} RUNTIME DESTINATION bin)
|
||||
|
||||
# Install & compile GTK schema file
|
||||
install(FILES ${SCHEMA_FILE} DESTINATION ${GSETTINGS_DIR})
|
||||
install(CODE "execute_process (COMMAND ${glib_schema_compiler} ${GSETTINGS_DIR})")
|
||||
|
|
|
@ -127,12 +127,12 @@ bool IPFS::shouldKillRunningProcess()
|
|||
std::string path = "/proc/" + std::to_string(pid) + "/exe";
|
||||
if (readlink(path.c_str(), pathbuf, sizeof(pathbuf) - 1) > 0)
|
||||
{
|
||||
// TODO: Compare version or file path location
|
||||
char beginPath[28] = "/usr/share/libreweb-browser";
|
||||
char beginPath[] = "/usr/share/libreweb-browser";
|
||||
// If the begin path does not path (!= 0), return true,
|
||||
// meaning the process will be killed.
|
||||
return (strncmp(pathbuf, beginPath, strlen(beginPath)) != 0);
|
||||
}
|
||||
// TODO: Compare IPFS version as well, maybe?
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "mainwindow.h"
|
||||
|
||||
#include "project_config.h"
|
||||
#include "md-parser.h"
|
||||
#include "menu.h"
|
||||
#include "file.h"
|
||||
|
@ -10,14 +11,21 @@
|
|||
#include <glibmm/miscutils.h>
|
||||
#include <glibmm/main.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <glibmm/miscutils.h>
|
||||
#include <cmark-gfm.h>
|
||||
#include <pthread.h>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
/**
|
||||
* For info: NDEBUG variable be used for debugging purpose, example:
|
||||
* #ifdef NDEBUG
|
||||
* #endif
|
||||
*/
|
||||
MainWindow::MainWindow()
|
||||
: accelGroup(Gtk::AccelGroup::create()),
|
||||
m_menu(accelGroup),
|
||||
: m_accelGroup(Gtk::AccelGroup::create()),
|
||||
m_settings(),
|
||||
m_menu(m_accelGroup),
|
||||
m_draw_main(*this),
|
||||
m_draw_secondary(*this),
|
||||
m_vbox(Gtk::ORIENTATION_VERTICAL, 0),
|
||||
|
@ -41,7 +49,20 @@ MainWindow::MainWindow()
|
|||
set_title(m_appName);
|
||||
set_default_size(1000, 800);
|
||||
set_position(Gtk::WIN_POS_CENTER);
|
||||
add_accel_group(accelGroup);
|
||||
add_accel_group(m_accelGroup);
|
||||
|
||||
// Change schema directory when browser is not installed
|
||||
if (!this->isInstalled())
|
||||
{
|
||||
std::string schemaDir = std::string(BINARY_DIR) + "/gsettings";
|
||||
std::cout << "INFO: Use settings from: " << schemaDir << std::endl;
|
||||
Glib::setenv("GSETTINGS_SCHEMA_DIR", schemaDir);
|
||||
}
|
||||
// Load schema settings file
|
||||
m_settings = Gio::Settings::create("org.libreweb.browser");
|
||||
set_default_size(m_settings->get_int("width"), m_settings->get_int("height"));
|
||||
if (m_settings->get_boolean("maximized"))
|
||||
this->maximize();
|
||||
|
||||
m_statusPopover.set_position(Gtk::POS_BOTTOM);
|
||||
m_statusPopover.set_size_request(200, 80);
|
||||
|
@ -53,7 +74,10 @@ MainWindow::MainWindow()
|
|||
// Timeouts
|
||||
this->statusTimerHandler = Glib::signal_timeout().connect(sigc::mem_fun(this, &MainWindow::update_connection_status), 3000);
|
||||
|
||||
// Connect signals
|
||||
// Window signals
|
||||
this->signal_delete_event().connect(sigc::mem_fun(this, &MainWindow::delete_window));
|
||||
|
||||
// Menu & toolbar signals
|
||||
m_menu.new_doc.connect(sigc::mem_fun(this, &MainWindow::new_doc)); /*!< Menu item for new document */
|
||||
m_menu.open.connect(sigc::mem_fun(this, &MainWindow::open)); /*!< Menu item for opening existing document */
|
||||
m_menu.save.connect(sigc::mem_fun(this, &MainWindow::save)); /*!< Menu item for save document */
|
||||
|
@ -372,13 +396,14 @@ MainWindow::MainWindow()
|
|||
// timer will do the updates later
|
||||
this->update_connection_status();
|
||||
|
||||
#ifdef NDEBUG
|
||||
// Show start page by default
|
||||
go_home();
|
||||
#else
|
||||
// Load test.md file in debug
|
||||
doRequest("file://../../test.md", true);
|
||||
#endif
|
||||
// Show homepage if debugging is disabled
|
||||
#ifdef NDEBUG
|
||||
go_home();
|
||||
#else
|
||||
std::cout << "INFO: Running as Debug mode, opening test.md." << std::endl;
|
||||
// Load test file when developing
|
||||
doRequest("file://../../test.md", true);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -404,6 +429,20 @@ void MainWindow::doRequest(const std::string &path, bool setAddressBar, bool isH
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Called when Window is closed
|
||||
*/
|
||||
bool MainWindow::delete_window(GdkEventAny *any_event __attribute__((unused)))
|
||||
{
|
||||
// Save the schema settings
|
||||
m_settings->set_int("width", this->get_width());
|
||||
m_settings->set_int("height", this->get_height());
|
||||
m_settings->set_boolean("maximized", this->is_maximized());
|
||||
// Fullscreen will be availible with gtkmm-4.0
|
||||
//m_settings->set_boolean("fullscreen", this->is_fullscreen());
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Timeout slot: Update the IPFS connection status every x seconds
|
||||
*/
|
||||
|
@ -428,7 +467,7 @@ bool MainWindow::update_connection_status()
|
|||
// And also update text
|
||||
m_statusLabel.set_text("IPFS Network Stats:\n\nConnected peers: " + std::to_string(nrPeers) +
|
||||
"\nRate in: " + in + " kB/s" +
|
||||
"\nRate out: " + out + " kB/s");
|
||||
"\nRate out: " + out + " kB/s");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -809,6 +848,25 @@ void MainWindow::refresh()
|
|||
doRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Determing if browser is installed from current binary path, at runtime
|
||||
* \return true if the current running process is installed (to the installed prefix path)
|
||||
*/
|
||||
bool MainWindow::isInstalled()
|
||||
{
|
||||
char pathbuf[1024];
|
||||
memset(pathbuf, 0, sizeof(pathbuf));
|
||||
if (readlink("/proc/self/exe", pathbuf, sizeof(pathbuf) - 1) > 0)
|
||||
{
|
||||
// If current binary path starts with the install prefix, it's installed
|
||||
return (strncmp(pathbuf, INSTALL_PREFIX, strlen(INSTALL_PREFIX)) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true; // fallback; always installed
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::enableEdit()
|
||||
{
|
||||
// Inform the Draw class that we are creating a new document
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <gtkmm/searchbar.h>
|
||||
#include <gtkmm/searchentry.h>
|
||||
#include <gtkmm/paned.h>
|
||||
#include <giomm/settings.h>
|
||||
#include <thread>
|
||||
|
||||
/**
|
||||
|
@ -33,6 +34,7 @@ public:
|
|||
|
||||
protected:
|
||||
// Signal handlers
|
||||
bool delete_window(GdkEventAny* any_event);
|
||||
bool update_connection_status();
|
||||
void cut();
|
||||
void copy();
|
||||
|
@ -60,7 +62,8 @@ protected:
|
|||
void show_source_code_dialog();
|
||||
void get_heading();
|
||||
|
||||
Glib::RefPtr<Gtk::AccelGroup> accelGroup; /*!< Accelerator group, used for keyboard shortcut bindings */
|
||||
Glib::RefPtr<Gtk::AccelGroup> m_accelGroup; /*!< Accelerator group, used for keyboard shortcut bindings */
|
||||
Glib::RefPtr<Gio::Settings> m_settings; /*!< Settings to store our preferences, even during restarts */
|
||||
|
||||
// Child widgets
|
||||
Menu m_menu;
|
||||
|
@ -158,6 +161,7 @@ private:
|
|||
sigc::connection statusTimerHandler;
|
||||
IPFS ipfs;
|
||||
|
||||
bool isInstalled();
|
||||
void enableEdit();
|
||||
void disableEdit();
|
||||
void postDoRequest(const std::string &path, bool setAddressBar, bool isHistoryRequest);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schemalist>
|
||||
<schema path="/org/libreweb/browser/" id="org.libreweb.browser">
|
||||
<key name="width" type="i">
|
||||
<default>1000</default>
|
||||
<summary>Window width</summary>
|
||||
</key>
|
||||
<key name="height" type="i">
|
||||
<default>800</default>
|
||||
<summary>Window height</summary>
|
||||
</key>
|
||||
<key name="maximized" type="b">
|
||||
<default>false</default>
|
||||
<summary>Is window maximized</summary>
|
||||
</key>
|
||||
<key name="fullscreen" type="b">
|
||||
<default>false</default>
|
||||
<summary>Is window fullscreen</summary>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
|
@ -1,10 +1,13 @@
|
|||
#ifndef INCLUDE_GUARD
|
||||
#define INCLUDE_GUARD
|
||||
#ifndef PROJECT_CONFIG_H
|
||||
#define PROJECT_CONFIG_H
|
||||
|
||||
#define PROJECT_NAME "@PROJECT_NAME@"
|
||||
#define PROJECT_VER "@PROJECT_VERSION@"
|
||||
#define PROJECT_VER_MAJOR "@PROJECT_VERSION_MAJOR@"
|
||||
#define PROJECT_VER_MINOR "@PROJECT_VERSION_MINOR@"
|
||||
#define PTOJECT_VER_PATCH "@PROJECT_VERSION_PATCH@"
|
||||
#define PROJECT_VER_PATCH "@PROJECT_VERSION_PATCH@"
|
||||
|
||||
#endif // INCLUDE_GUARD
|
||||
#define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
|
||||
#define BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@"
|
||||
|
||||
#endif // PROJECT_CONFIG_H
|
Loading…
Reference in New Issue