Yoda - Browser for Gemini protocol
GTK 4 / Libadwaita client written in Rust
Important
Project in development!
- Multi-tab
- Hotkeys
- Bookmarks
- Build-in multimedia support
- Certificates
- Downloads
- History
- Proxy
- Session
- Window
- Size
- Tabs
- Pin
- Page
- Content (cache)
- Meta
- Title
- Navigation
- Request
- History
- Window
- User settings
- Gemini
- Status code
- Success
-
20
-
- Input
-
10
Input -
11
Sensitive input
-
- Redirection
-
30
Temporary -
31
Permanent
-
- Temporary failure
-
40
Unspecified condition -
41
Server unavailable -
42
CGI error -
43
Proxy error -
44
Slow down
-
- Permanent failure
-
50
General -
51
Not found -
52
Gone -
53
Proxy request refused -
59
Bad request
-
- Client certificates
-
60
Certificate requested -
61
Certificate not authorized -
62
Certificate not valid
-
- Success
- Gemtext (by ggemtext)
- Code (inline/multiline)
- Inline
- Multiline
- Alt
- Terminal emulation*
- Syntax highlight*
- Header
- H1
- H2
- H3
- Link
- Address
- Date
- Alt
- List
- Quote
- Code (inline/multiline)
- Gemfeed
- Titan
- Status code
- NEX - useful for networks with build-in encryption (e.g. Yggdrasil)
-
file://
- localhost browser -
config://
- low-level key/value settings editor
-
text/gemini
-
text/plain
-
image/gif
-
image/jpeg
-
image/png
-
image/webp
-
image/svg+xml
-
audio/flac
-
audio/mpeg
-
audio/ogg
Make sure your system support:
- Glib 2.56+
- GTK 4.10+
- Libadwaita 1.6+
Use rustup installer to setup latest Rust compiler and Cargo package manager:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
todo
sudo dnf install git gcc\
cairo-devel glib2-devel gtk4-devel libadwaita-devel pango-devel\
sqlite-devel
cargo install Yoda
git clone https://github.com/YGGverse/Yoda.git
cd Yoda
cargo build
Quick start guide and maintenance protocol
- Use modern path pattern
- One module implements one GTK widget, it may include additional helper files in same location (like template, CSS or DB API)
- For children widget - create children module, located according to hierarchy
- Every module should be as minimal as possible, separate:
- different tasks
- massive structures
- structures with implementation
- Every module must:
- encapsulate members - use objects, not static names (unlike native GTK actions API)
- implement only one public API
struct
per file (same as one file for one class)- implementable
struct
is public, where it members - private
- implementable
- contain main
struct
implementation:- at least one constructor that must:
- have common for application names:
from
,new
or/andnew_rc
,new_mutex
, etc - on return object in container - grant ownership for new
Self
object created
- have common for application names:
- public
activate
action if the new object can not be activated on construct - public
link
getter for GTKwidget
(parental composition)
- at least one constructor that must:
- Public API oriented to simple (
integer
,boolean
), standard (std::*
) or system-wide (gio
,glib
, etc) data types usage to reduce internal dependencies from app implementation
- SQLite used to operate with user profile: for example, restore and save widget sessions, manage auth, history, bookmarks, etc
- Database stored in system config directory (could be detected simply using browser tools menu)
- Structure of table should not be modified on
CARGO_PKG_VERSION_PATCH
change - Every
browser
mod may have own table, where table must:- contain same name as mod location, for example
app_browser_widget
forsrc/app/browser/widget.rs
- every table include autoincrement
id
column and parental primary ID if exist- column name for parental ID must have absolute namespace prefix, for example
app_browser_id
column forapp_browser_widget
table. For example, if the table has few parental keys, column set could beid
,parent_one_id
,parent_two_id
,some_data
- column name for parental ID must have absolute namespace prefix, for example
- contain same name as mod location, for example
- todo
- version control for auto-migrations
- transactions support for update operations
- Operate with action objects instead of names like
win.action
. This allows to follow encapsulation, by the our goal, module must know nothing about parent presets. For example, define some action in parent, then delegate object created as construction argument - Started refactory on separate widgets implementation to separated mods, because widgets may contain own tables in database and require additional mods dependencies like ORM API todo
- Before commit, please make sure:
- new branch created for every new PR
git checkout -b 'contribution-name'
- new code follows common rustfmt style
cargo fmt --check
- run
cargo clippy
for final optimization
- new branch created for every new PR
- Package version in repository should be increased immediately after stable release on crates.io and before apply new changes
- Currently, profile data stored in separated sub-directories, auto-created on every
CARGO_PKG_VERSION_MAJOR
or/andCARGO_PKG_VERSION_MINOR
change
- ggemtext - Glib-oriented Gemtext API
- ggemini - Glib-oriented client for Gemini protocol