Compare commits
	
		
			44 Commits
		
	
	
		
			f1982d015d
			...
			aec21c71a6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| aec21c71a6 | |||
| cd2b6a3257 | |||
| d65dc93af7 | |||
| b87693e4c5 | |||
| e2c81f2595 | |||
| 0253c5e80a | |||
| d17fb92bb6 | |||
| eefa3cfb45 | |||
| 16d43ac601 | |||
| 4784a0ad26 | |||
| 3beef82ca6 | |||
| 38cee8fd24 | |||
| 5b1aab5e0c | |||
| 98f6d5630f | |||
| 1cf68bb1fe | |||
| a24af4aad1 | |||
| 8d2811c5f9 | |||
| 995f455ece | |||
| 28a28b491d | |||
| c08c4f48de | |||
| 8dc67aaa16 | |||
| 84df2273eb | |||
| 6ef555fc44 | |||
| a8be16b1ee | |||
| c46e2ba398 | |||
| 5fb7e79ad5 | |||
| 49a005f929 | |||
| c2bffc09ce | |||
| 00d498851c | |||
| 98114362d9 | |||
| 85942a60bd | |||
| 574cdd30ce | |||
| 230f472e3a | |||
| 5331760a83 | |||
| 6ae0811000 | |||
| 3734dcd2d1 | |||
| 4e3bb826ba | |||
| 0ba58087e0 | |||
| 52aacc6dac | |||
| b129954d4d | |||
| b32749aa6e | |||
| a4f8ad8ae2 | |||
| f8b4e9ff4a | |||
| 17ff6bb780 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
rose
 | 
			
		||||
							
								
								
									
										103
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								README.md
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -1,58 +1,102 @@
 | 
			
		|||
## Rosenrot
 | 
			
		||||
 | 
			
		||||
A small browser forked from [rose](https://github.com/mini-rose/rose). 
 | 
			
		||||
Rosenrot is a small browser forked from an earlier version of [rose](https://github.com/mini-rose/rose). It has some additional quality of life improvements tailored to my (@NunoSempere) tastes and setup, and detailed installation instructions for Ubuntu 20.04.
 | 
			
		||||
 | 
			
		||||
- Rose is a minimal browser based on webkit2gtk which aims to be a "basement for creating your own browser using [the] gtk and webkit libraries". 
 | 
			
		||||
- Rosenrot is my fork from rose. It has accumulated cruft that I like, like a "readability" plugin that simplifies annoying websites like [Matt Levine's Money Stuff newsletter](https://www.bloomberg.com/opinion/articles/2022-10-18/matt-levine-s-money-stuff-credit-suisse-was-a-reverse-meme-stock).
 | 
			
		||||
- Rosenrot is also a song by the German hardcore rock band [Rammstein](https://www.youtube.com/watch?v=af59U2BRRAU).
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
You can see some screenshots in the [screenshots](./screenshots) folder.
 | 
			
		||||
 | 
			
		||||
### Features
 | 
			
		||||
 | 
			
		||||
- tabs, cookies, caching
 | 
			
		||||
- minimal ui, autohiding elements
 | 
			
		||||
- ~467L core code (the rose.c file)
 | 
			
		||||
- custom gtk and websites css
 | 
			
		||||
- builtin rose-mklink script for in-shell static links
 | 
			
		||||
- A few quality of life improvements.
 | 
			
		||||
  - Optional adblocking through [wyebadblock](https://github.com/jun7/wyebadblock)
 | 
			
		||||
  - Plugin system:
 | 
			
		||||
    - Libre redirect: Redirect annoying websites to open source frontends
 | 
			
		||||
    - Readability: Strip webpages of unnecessary elements for ease of reading with a custom shortcut
 | 
			
		||||
    - Custom style: Override the css of predetermined websites
 | 
			
		||||
    - Stand in plugin: Mimick function definitions which do nothing for the above plugins so that they can be quickly removed
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
### Installation
 | 
			
		||||
 | 
			
		||||
Install dependencies, then:
 | 
			
		||||
You can see detailed instructions [here](./user-scripts/ubuntu-20.04/install-with-dependencies.sh), for Ubuntu 20.04 in particular—though they should generalize easily to other distributions. Or a video installing rosenrot in a fresh Ubuntu 20.04 virtual machine [here](https://video.nunosempere.com/w/t3oAvJLPHTSAMViQ6zbwTV).
 | 
			
		||||
 | 
			
		||||
The general steps are to install dependencies, and then
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
make build
 | 
			
		||||
make install # or sudo make install
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You can also see more detailed instructions [here](./user-scripts/ubuntu-20.04/install-with-dependencies.sh), for Ubuntu 20.04 in particular—though they should generalize trivially. Or a video installing rosenrot in a fresh Ubuntu 20.04 virtual machine [here](https://video.nunosempere.com/w/t3oAvJLPHTSAMViQ6zbwTV).
 | 
			
		||||
### Usage
 | 
			
		||||
 | 
			
		||||
### 👐 Contribute
 | 
			
		||||
After building:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
./rose
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
After installing:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
rose
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You can also create a rose.desktop file so that it will show up in your desktop environment. You can see this documented [here](./user-scripts/ubuntu-20.04/install-with-dependencies.sh).
 | 
			
		||||
 | 
			
		||||
### Features
 | 
			
		||||
 | 
			
		||||
- Tabs, cookies, caching
 | 
			
		||||
- Minimal ui, autohiding elements
 | 
			
		||||
- ~464L core code (the rose.c file)
 | 
			
		||||
- Customize appearance of the browser through css
 | 
			
		||||
- Built-in rose-mklink script for in-shell static links
 | 
			
		||||
- Optional adblocking through [wyebadblock](https://github.com/jun7/wyebadblock)
 | 
			
		||||
- Max number of tabs (by default 8), configurable.
 | 
			
		||||
- Plugin system, seeded with:
 | 
			
		||||
  - Libre redirect: Redirect annoying websites to open source frontends
 | 
			
		||||
  - Readability: Strip webpages of unnecessary elements for ease of reading with a custom shortcut
 | 
			
		||||
  - Custom style: Override the css of predetermined websites
 | 
			
		||||
  - Stand in plugin: Mimick function definitions which do nothing for the above plugins so that they can be quickly removed
 | 
			
		||||
 | 
			
		||||
You can see some screenshots in the [screenshots](./screenshots) folder.
 | 
			
		||||
 | 
			
		||||
## Relationship with [rose](https://github.com/mini-rose/rose)
 | 
			
		||||
 | 
			
		||||
- Rose is a minimal browser based on webkit2gtk. Previously, it described itself as aiming to be a "basement for creating your own browser using [the] gtk and webkit libraries". 
 | 
			
		||||
- Rosenrot is my (@NunoSempere's) fork from rose. It has accumulated quality of life features/cruft that I like, like a "readability" plugin that simplifies annoying websites like [Matt Levine's Money Stuff newsletter](https://www.bloomberg.com/opinion/articles/2022-10-18/matt-levine-s-money-stuff-credit-suisse-was-a-reverse-meme-stock). It also incorporates ad-blocking.
 | 
			
		||||
- Rosenrot is also a song by the German hardcore rock band [Rammstein](https://www.youtube.com/watch?v=af59U2BRRAU).
 | 
			
		||||
 | 
			
		||||
### Contribute
 | 
			
		||||
 | 
			
		||||
- Contribute upstream to [github.com/mini-rose/rose](https://github.com/mini-rose/) for core functionality changes.
 | 
			
		||||
- Contribute here for quality of life improvements, by sending a pull request on Github.
 | 
			
		||||
 | 
			
		||||
### Cool things
 | 
			
		||||
 | 
			
		||||
I just found out that you can inspect a GTK application with the GTK explorer if you set a certain command-line variable. Try this with `make inspect`.
 | 
			
		||||
 | 
			
		||||
### Known bugs/gotchas.
 | 
			
		||||
 | 
			
		||||
- [x] ~~Doesn't work with when Spanish is selected as the language, for some reason~~ => Previously misdiagnosed. The real issue was that it freezes when interacting with [Espanso](https://espanso.org/) substitutions, which I had set-up automatically on my machine when using words containing an ñ, like my own name, Nuño.
 | 
			
		||||
- [ ] At some point, I tried to install libsoup-3 and borked some unknown installation option/paths. So now I need to run rose with `GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/ /bin/rose` (or put `export GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/` in my .bashrc). This won't affect new users though, just double checked on a fresh machine.
 | 
			
		||||
- [ ] By default the searchbar is pretty gigantic. I've made this so because I'm a bit myopic, but also work with my laptop in a laptop stand. Anyways, if you are a more normal person you can change this in the style.css.
 | 
			
		||||
- [ ] The style.css usage isn't updated until installation. This is because by default rose uses the theme located in /usr/share/themes/rose/style.css, and that file isn't updated until make install.
 | 
			
		||||
 | 
			
		||||
### To do
 | 
			
		||||
 | 
			
		||||
- [ ] Look at using relative rather than absolute paths
 | 
			
		||||
#### Quality of life:
 | 
			
		||||
 | 
			
		||||
- [ ] Add css for js alerts
 | 
			
		||||
- [ ] Figure out if downloading files is doable.
 | 
			
		||||
  - [x] Add custom alert whose css can be customized
 | 
			
		||||
  - [ ] Debug problems, e.g., this version is non-blocking.
 | 
			
		||||
- [ ] Figure out better way to have plugins
 | 
			
		||||
- [ ] Double check newtab/next-tab behavior
 | 
			
		||||
- [ ] Find out what each of the css elements refers to.
 | 
			
		||||
- [ ] Use something other than Whatsapp as an example syslink.
 | 
			
		||||
- [ ] Document creating new applications, e.g., as in [Asana for Linux](https://git.nunosempere.com/NunoSempere/asana-for-linux)
 | 
			
		||||
- [ ] Add list of similar projects: <https://github.com/qutebrowser/qutebrowser#similar-projects>
 | 
			
		||||
 | 
			
		||||
#### Maintenance 
 | 
			
		||||
 | 
			
		||||
- [ ] Set [`webkit_web_context_set_sandbox_enabled`](<https://webkitgtk.org/reference/webkit2gtk/2.36.8/WebKitWebContext.html#webkit-web-context-set-sandbox-enabled>), as recommended [here](<https://blogs.gnome.org/mcatanzaro/2022/11/04/stop-using-qtwebkit/>)
 | 
			
		||||
- [ ] Use something other than Whatsapp as an example syslink.
 | 
			
		||||
- [ ] Fix bug about distorted audio. Maybe related to [this pipewire issue](<https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1547>)?
 | 
			
		||||
- [ ] Upgrade to GTK-4 / Webkitgtk 6.0? Will take a fair amount of time, since these are not available on Ubuntu 20.04.
 | 
			
		||||
 | 
			
		||||
Done:
 | 
			
		||||
#### Previously done
 | 
			
		||||
 | 
			
		||||
- [x] Add a shortcut for hiding the search tab. => Already exists: Ctrl+K
 | 
			
		||||
- [x] Find out what each of the css elements refers to. => done, see make inspect
 | 
			
		||||
- [x] Figure out if downloading files is doable. => it is
 | 
			
		||||
- [x] Look at using relative rather than absolute paths for configuration. => now makefile is a bit smarter
 | 
			
		||||
- [x] Streamline installation a bit
 | 
			
		||||
  - [x] Substitute paths in makefile
 | 
			
		||||
  - [x] Create cache directory automatically
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +118,3 @@ Done:
 | 
			
		|||
  - And for actually opening links with the href new_tab option.
 | 
			
		||||
  - Links: [1](<https://docs.gtk.org/gobject/func.signal_connect.html>), [2](<https://webkitgtk.org/reference/webkit2gtk/2.37.90/signal.AutomationSession.create-web-view.html>), [3](<https://webkitgtk.org/reference/webkit2gtk/2.26.0/WebKitWebView.html#WebKitWebView-create>), [4](<https://stackoverflow.com/questions/40180757/webkit2gtk-get-new-window-link>)
 | 
			
		||||
 | 
			
		||||
### Known bugs
 | 
			
		||||
 | 
			
		||||
- [ ] Doesn't work with when Spanish is selected as the language, for some reason. 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								config.h
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -8,19 +8,21 @@
 | 
			
		|||
	    "enable-smooth-scrolling", false
 | 
			
		||||
 | 
			
		||||
#define GTK "gtk-application-prefer-dark-theme", false, "gtk-enable-animations", false
 | 
			
		||||
#define ROSE_HOMEPAGE true
 | 
			
		||||
#define HOME ROSE_HOMEPAGE ? "file:///home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose-images/rose-homepage.png" : "https://lite.duckduckgo.com/html"
 | 
			
		||||
#define SEARCH "https://lite.duckduckgo.com/html/?q=%s"
 | 
			
		||||
#define ROSE_HOMEPAGE false
 | 
			
		||||
#define SEARCH "https://search.nunosempere.com/search?q=%s" // "https://lite.duckduckgo.com/html/?q=%s"
 | 
			
		||||
#define HOME ROSE_HOMEPAGE ? "file:///home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose-images/rose-homepage.png" : "https://search.nunosempere.com/"
 | 
			
		||||
// #define HOME ROSE_HOMEPAGE ? "file:///home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose-images/rose-homepage.png" : "https://search.nunosempere.com/"
 | 
			
		||||
#define CACHE_DIR "/home/loki/.cache/rose"
 | 
			
		||||
 | 
			
		||||
#define WIDTH 1920
 | 
			
		||||
#define WIDTH 1920 // 960 for half-width, 1920 for full width
 | 
			
		||||
#define HEIGHT 1080
 | 
			
		||||
#define SEARCH_BAR_SIZE 1200
 | 
			
		||||
#define KEY(x) GDK_KEY_##x
 | 
			
		||||
#define ZOOM 1.4  /* Starting zoom level.*/
 | 
			
		||||
#define ZOOM 1.6  /* Starting zoom level.*/
 | 
			
		||||
#define ZOOM_VAL .1 /* Zooming value in zoomin/zoomout functions */
 | 
			
		||||
#define BG_COLOR "#FEFEFE" /* "FEFEFE", "#1E1E2E" */
 | 
			
		||||
#define DEBUG false 
 | 
			
		||||
#define DEBUG false
 | 
			
		||||
#define MAX_NUM_TABS 8 // set to 0 or false if you want unlimited tabs, or look at the relevant rose.c code.
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	goback,
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +69,7 @@ static struct {
 | 
			
		|||
    { CTRL,        KEY(w),          close_tab          },
 | 
			
		||||
    { 0x0,         KEY(F11),        toggle_fullscreen  },
 | 
			
		||||
    { CTRL,        KEY(l),          show_searchbar     },
 | 
			
		||||
    { CTRL,        KEY(k),          hide_bar     },
 | 
			
		||||
    { CTRL,        KEY(semicolon),          hide_bar     },
 | 
			
		||||
    { CTRL,        KEY(f),          show_finder        },
 | 
			
		||||
    { CTRL,        KEY(n),          finder_next        },
 | 
			
		||||
    { CTRL | SFT,  KEY(N),          finder_prev        },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										24
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								makefile
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -6,7 +6,10 @@
 | 
			
		|||
# make uninstall
 | 
			
		||||
 | 
			
		||||
## C compiler
 | 
			
		||||
CC=gcc
 | 
			
		||||
CC=gcc # gcc: more options. Also I don't know whether tcc has error messages/debug options.
 | 
			
		||||
WARNINGS=-Wall
 | 
			
		||||
OPTIMIZED=-O3  #-Ofast
 | 
			
		||||
## CC=tcc # tcc: much faster
 | 
			
		||||
 | 
			
		||||
## Main file
 | 
			
		||||
SRC=rose.c
 | 
			
		||||
| 
						 | 
				
			
			@ -20,16 +23,17 @@ LIBS=`pkg-config --libs ${DEPS}`
 | 
			
		|||
 | 
			
		||||
## Optional adblocking
 | 
			
		||||
## depends on https://github.com/jun7/wyebadblock
 | 
			
		||||
ADBLOCK='-L/usr/lib/wyebrowser/adblock.so'
 | 
			
		||||
ADBLOCK=#'-L/usr/lib/wyebrowser/adblock.so'
 | 
			
		||||
 | 
			
		||||
## Plugins
 | 
			
		||||
LIBRE_REDIRECT=./plugins/libre_redirect/libre_redirect.c ./plugins/libre_redirect/str_replace_start.c 
 | 
			
		||||
READABILITY=./plugins/readability/readability.c 
 | 
			
		||||
LIBRE_REDIRECT=./plugins/libre_redirect/libre_redirect.c ./plugins/libre_redirect/str_replace_start.c ./plugins/libre_redirect/str_init.c 
 | 
			
		||||
CUSTOM_STYLES=./plugins/style/style.c
 | 
			
		||||
READABILITY=./plugins/readability/readability.c 
 | 
			
		||||
SHORTCUTS=./plugins/shortcuts/shortcuts.c
 | 
			
		||||
 | 
			
		||||
STAND_IN=./plugins/stand_in/stand_in.c # gives function definitions for the above, which do nothing
 | 
			
		||||
 | 
			
		||||
PLUGS=$(LIBRE_REDIRECT) $(READABILITY) $(CUSTOM_STYLES)
 | 
			
		||||
PLUGS=$(LIBRE_REDIRECT) $(READABILITY) $(CUSTOM_STYLES) $(SHORTCUTS)
 | 
			
		||||
# PLUGS=$(STAND_IN)
 | 
			
		||||
# Note that if you want some plugins but not others,
 | 
			
		||||
# You should edit the stand_in.c file
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +57,9 @@ DEFAULT_DIR=/home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot
 | 
			
		|||
CURRENT_DIR=`pwd`
 | 
			
		||||
 | 
			
		||||
build: $(SRC) $(PLUGS) $(CONFIG)
 | 
			
		||||
	# Recompute constants
 | 
			
		||||
	cd plugins/readability/ && sh recompute_READABILITY_N.sh
 | 
			
		||||
	cd plugins/style && sh recompute_STYLE_N.sh 
 | 
			
		||||
	# Make cache
 | 
			
		||||
	mkdir -p $(CURRENT_CACHE_DIR)
 | 
			
		||||
	# Hardcode cache path
 | 
			
		||||
| 
						 | 
				
			
			@ -62,9 +69,14 @@ build: $(SRC) $(PLUGS) $(CONFIG)
 | 
			
		|||
	find $(CURRENT_DIR) -type f -not -path "*.git*" -not -path "*makefile*" -exec \
 | 
			
		||||
		sed -i "s|$(DEFAULT_DIR)|$(CURRENT_DIR)|g" {} +
 | 
			
		||||
	# Compile rosenrot
 | 
			
		||||
	$(CC) $(DEBUG) $(INCS) $(PLUGS) $(SRC) -o rose $(LIBS) $(ADBLOCK)
 | 
			
		||||
	GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/
 | 
			
		||||
	$(CC) $(WARNINGS) $(OPTIMIZED) $(DEBUG) $(INCS) $(PLUGS) $(SRC) -o rose $(LIBS) $(ADBLOCK)
 | 
			
		||||
 | 
			
		||||
inspect: build
 | 
			
		||||
	GTK_DEBUG=interactive ./rose
 | 
			
		||||
 | 
			
		||||
install: rose
 | 
			
		||||
	GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/
 | 
			
		||||
	cp -f rose /usr/bin
 | 
			
		||||
	mkdir -p /usr/share/themes/rose
 | 
			
		||||
	cp style.css /usr/share/themes/rose/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,22 +2,16 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "str_init.h"
 | 
			
		||||
#include "str_replace_start.h"
 | 
			
		||||
 | 
			
		||||
#define LIBRE_N 19
 | 
			
		||||
#define LIBRE_N 50
 | 
			
		||||
 | 
			
		||||
/* Uncomment for debug */
 | 
			
		||||
/* #define DEBUG */
 | 
			
		||||
 | 
			
		||||
/* Inspired by https://libredirect.github.io/, but in C. */
 | 
			
		||||
 | 
			
		||||
void str_init(char* str, int n)
 | 
			
		||||
{
 | 
			
		||||
    for (int i = 0; i < n; i++)
 | 
			
		||||
        str[i] = ' ';
 | 
			
		||||
    str[n] = '\0';
 | 
			
		||||
} // could also use <https://manpages.ubuntu.com/manpages/impish/man3/strinit.3pub.html>
 | 
			
		||||
 | 
			
		||||
int libre_redirect(const char* uri, char* output)
 | 
			
		||||
{
 | 
			
		||||
    int l1 = strlen(uri);
 | 
			
		||||
| 
						 | 
				
			
			@ -36,23 +30,29 @@ int libre_redirect(const char* uri, char* output)
 | 
			
		|||
        strcpy(tmp_output, output);
 | 
			
		||||
 | 
			
		||||
        char* annoying_sites[] = {
 | 
			
		||||
            "https://www.youtube.com",
 | 
			
		||||
            "https://www.reddit.com",
 | 
			
		||||
            "https://www.youtube.com",
 | 
			
		||||
            "https://google.com",
 | 
			
		||||
            "https://medium.com",
 | 
			
		||||
            "https://translate.google.com",
 | 
			
		||||
            // "https://forum.effectivealtruism.org",
 | 
			
		||||
            "https://www.bloomberg.com",
 | 
			
		||||
            "https://twitter.com"
 | 
			
		||||
            "https://www.royalroad.com",
 | 
			
		||||
						"https://genius.com",
 | 
			
		||||
						// "https://archive.org",
 | 
			
		||||
            // "https://twitter.com"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        char* alternatives[] = {
 | 
			
		||||
            "https://old.reddit.com", // "https://teddit.nunosempere.com",
 | 
			
		||||
            "https://yt.artemislena.eu",
 | 
			
		||||
            "https://teddit.nunosempere.com",
 | 
			
		||||
            "https://search.nunosempere.com",
 | 
			
		||||
            "https://scribe.rip",
 | 
			
		||||
            "https://simplytranslate.org/",
 | 
			
		||||
            // "https://ea.greaterwrong.com",
 | 
			
		||||
            "https://translate.riverside.rocks/",
 | 
			
		||||
            "https://archive.is/https://www.bloomberg.com",
 | 
			
		||||
            "https://nitter.net"
 | 
			
		||||
            "https://royalread.nunosempere.com",
 | 
			
		||||
						"https://dumb.vern.cc",
 | 
			
		||||
						// "https://wayback.nunosempere.com",
 | 
			
		||||
            // "https://nitter.net"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        len = sizeof(annoying_sites) / sizeof(annoying_sites[0]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define LIBRE_N 19
 | 
			
		||||
#define LIBRE_N 50
 | 
			
		||||
 | 
			
		||||
int libre_redirect(const char* uri, char* uri_filtered);
 | 
			
		||||
void str_init(char* str, int n);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								plugins/libre_redirect/str_init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								plugins/libre_redirect/str_init.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
void str_init(char* str, int n)
 | 
			
		||||
{
 | 
			
		||||
    for (int i = 0; i < n; i++)
 | 
			
		||||
        str[i] = ' ';
 | 
			
		||||
    str[n] = '\0';
 | 
			
		||||
} // could also use <https://manpages.ubuntu.com/manpages/impish/man3/strinit.3pub.html>
 | 
			
		||||
							
								
								
									
										1
									
								
								plugins/libre_redirect/str_init.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								plugins/libre_redirect/str_init.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
void str_init(char* str, int n);
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#define READABILITY_N 85133 + 1000
 | 
			
		||||
#define READABILITY_N 85314 + 1000
 | 
			
		||||
 | 
			
		||||
void read_readability_js(char* string)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
#ifndef READABILITY
 | 
			
		||||
#define READABILITY
 | 
			
		||||
 | 
			
		||||
#define READABILITY_N 85133 + 1000
 | 
			
		||||
#define READABILITY_N 85314 + 1000
 | 
			
		||||
 | 
			
		||||
void read_readability_js(char* string);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2386,10 +2386,17 @@ if (document.domain == "archive.is" ){
 | 
			
		|||
			display: none !important;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
	/* Matt Levine's Money Stuff specific stuff: */
 | 
			
		||||
 | 
			
		||||
	p > span > em {
 | 
			
		||||
			display: none !important;
 | 
			
		||||
	}
 | 
			
		||||
	/* ^ deletes the subscribe prompt in Matt Levine's Money Stuff. */
 | 
			
		||||
  iframe {
 | 
			
		||||
	  display: none;
 | 
			
		||||
  }
 | 
			
		||||
	#div[id^='stickypbModal'] {
 | 
			
		||||
	 display: none;
 | 
			
		||||
	}
 | 
			
		||||
  `
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
#!/bin/bash
 | 
			
		||||
function sedr(){
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
sed_wrapper()
 | 
			
		||||
{
 | 
			
		||||
  find ./ -type f -exec sed -i -e "$1" {} \;
 | 
			
		||||
} ## e.g., sedr "s/target/replacement/g"
 | 
			
		||||
 | 
			
		||||
READABILITY_N=$(wc -c readability.js | cut -d " " -f 1)
 | 
			
		||||
sedr "s/^#define READABILITY_N .*/#define READABILITY_N $READABILITY_N + 1000/g"
 | 
			
		||||
READABILITY_N=`wc -c readability.js | cut -d " " -f 1`
 | 
			
		||||
sed_wrapper "s/^#define READABILITY_N .*/#define READABILITY_N $READABILITY_N + 1000/g"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										7
									
								
								plugins/shortcuts/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								plugins/shortcuts/README.md
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
## About
 | 
			
		||||
 | 
			
		||||
This code automatically redirects shortcuts to their longer expansions. Similar to DuckDuckGo's bangs (<https://duckduckgo.com/bangs>)
 | 
			
		||||
 | 
			
		||||
Note that Whoogle (the default search engine) also has its own bangs!
 | 
			
		||||
- See: https://github.com/benbusby/whoogle-search/blob/main/app/utils/bangs.py
 | 
			
		||||
- and https://duckduckgo.com/bang.v255.js
 | 
			
		||||
							
								
								
									
										74
									
								
								plugins/shortcuts/shortcuts.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								plugins/shortcuts/shortcuts.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,74 @@
 | 
			
		|||
#include <stdbool.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "../libre_redirect/str_init.h"
 | 
			
		||||
#include "../libre_redirect/str_replace_start.h"
 | 
			
		||||
 | 
			
		||||
#define SHORTCUT_N 41
 | 
			
		||||
 | 
			
		||||
/* Uncomment for debug */
 | 
			
		||||
/* #define DEBUG */
 | 
			
		||||
 | 
			
		||||
/* Inspired by https://duckduckgo.com/bangs */
 | 
			
		||||
 | 
			
		||||
int shortcut_expand(const char* uri, char* output)
 | 
			
		||||
{
 | 
			
		||||
    printf("SHORTCUT EXPAND!\n");
 | 
			
		||||
    int l1 = strlen(uri);
 | 
			
		||||
    int l2 = strlen(output);
 | 
			
		||||
    int len;
 | 
			
		||||
    char tmp_uri[l2++];
 | 
			
		||||
    char tmp_output[l2++];
 | 
			
		||||
 | 
			
		||||
    if ((l2 - l1) < SHORTCUT_N) {
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
        printf("Not enough memory\n");
 | 
			
		||||
#endif
 | 
			
		||||
        return 1; // not enough memory.
 | 
			
		||||
    } else {
 | 
			
		||||
        strcpy(tmp_uri, uri); // strcpy also copies the terminating '\0'
 | 
			
		||||
        strcpy(tmp_output, output);
 | 
			
		||||
 | 
			
		||||
        char* shortcuts[] = {
 | 
			
		||||
            "!fnf",
 | 
			
		||||
            "!fnc",
 | 
			
		||||
            "!hn",
 | 
			
		||||
            "!hnb"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        char* expansions[] = {
 | 
			
		||||
            "https://forum.nunosempere.com/frontpage",
 | 
			
		||||
            "https://forum.nunosempere.com/comments",
 | 
			
		||||
            "https://news.ycombinator.com",
 | 
			
		||||
            "https://news.ycombinator.com/best",
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // len = sizeof(shortcuts) / sizeof(shortcuts[0]);
 | 
			
		||||
        len = sizeof(shortcuts) / sizeof(char*);
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < len; i++) {
 | 
			
		||||
            int replace_check = str_replace_start(tmp_uri, shortcuts[i],
 | 
			
		||||
                expansions[i], output);
 | 
			
		||||
            if (replace_check == 2) {
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
                printf("tmp_uri: %s\n", tmp_uri);
 | 
			
		||||
                printf("output: %s\n", output);
 | 
			
		||||
#endif
 | 
			
		||||
                return 2;
 | 
			
		||||
            } else if (replace_check == 1) {
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
                printf("replace_check failed\n");
 | 
			
		||||
#endif
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
            strcpy(tmp_uri, output);
 | 
			
		||||
            str_init(output, l2);
 | 
			
		||||
        }
 | 
			
		||||
        strcpy(output, tmp_uri);
 | 
			
		||||
    }
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
    printf("No match found\n\n");
 | 
			
		||||
#endif
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								plugins/shortcuts/shortcuts.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								plugins/shortcuts/shortcuts.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define SHORTCUT_N 41
 | 
			
		||||
 | 
			
		||||
int shortcut_expand(const char* uri, char* output);
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
#!/bin/bash
 | 
			
		||||
function sedr(){
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
sed_wrapper()
 | 
			
		||||
{
 | 
			
		||||
  find ./ -type f -exec sed -i -e "$1" {} \;
 | 
			
		||||
} ## e.g., sedr "s/target/replacement/g"
 | 
			
		||||
 | 
			
		||||
STYLE_N=$(wc -c style.js | cut -d " " -f 1)
 | 
			
		||||
sedr "s/^#define STYLE_N .*/#define STYLE_N $STYLE_N + 1/g"
 | 
			
		||||
STYLE_N=`wc -c style.js | cut -d " " -f 1`
 | 
			
		||||
sed_wrapper "s/^#define STYLE_N .*/#define STYLE_N $STYLE_N + 100/g"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#define STYLE_N 1393 + 1
 | 
			
		||||
#define STYLE_N 4748 + 100
 | 
			
		||||
 | 
			
		||||
void read_style_js(char* string)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
#ifndef STYLE
 | 
			
		||||
#define STYLE
 | 
			
		||||
 | 
			
		||||
#define STYLE_N 1393 + 1
 | 
			
		||||
#define STYLE_N 4748 + 100
 | 
			
		||||
 | 
			
		||||
void read_style_js(char* string);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ if (document.domain == "forum.effectivealtruism.org"){
 | 
			
		|||
 | 
			
		||||
if (document.domain == "mail.proton.me" ){
 | 
			
		||||
	styles = `
 | 
			
		||||
	    /*
 | 
			
		||||
			.item-container-row.read, .item-container.read {
 | 
			
		||||
					background-color: white;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +37,66 @@ if (document.domain == "mail.proton.me" ){
 | 
			
		|||
			.selection .item-container-row.item-is-selected, .item-container.item-is-selected {
 | 
			
		||||
					background-color: var(--selection-background-color) !important;
 | 
			
		||||
			}
 | 
			
		||||
     zoom: 0.625 !important;
 | 
			
		||||
			*/
 | 
			
		||||
	`
 | 
			
		||||
}
 | 
			
		||||
if (document.domain == "forum.nunosempere.com" ){
 | 
			
		||||
  styles = `
 | 
			
		||||
   body {
 | 
			
		||||
     zoom: 0.625 !important;
 | 
			
		||||
	 }
 | 
			
		||||
  `
 | 
			
		||||
}
 | 
			
		||||
if (document.domain == "search.nunosempere.com" ){
 | 
			
		||||
  styles = `
 | 
			
		||||
   body {
 | 
			
		||||
     /* zoom: 1.8; */
 | 
			
		||||
	 }
 | 
			
		||||
 | 
			
		||||
   footer {
 | 
			
		||||
     display: none;
 | 
			
		||||
	 }
 | 
			
		||||
  `
 | 
			
		||||
}
 | 
			
		||||
if (document.domain == "twitter.com" ){
 | 
			
		||||
  styles = `
 | 
			
		||||
	/* hide promoted tweets */
 | 
			
		||||
	:has(meta[property="og:site_name"][content="Twitter"])
 | 
			
		||||
		[data-testid="cellInnerDiv"]:has(svg + [dir="auto"]) {
 | 
			
		||||
		display: none;
 | 
			
		||||
	}
 | 
			
		||||
	[data-testid^="placementTracking"] {
 | 
			
		||||
		display: none;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  /* hide what's happening section */
 | 
			
		||||
  :has(meta[property="og:site_name"][content="Twitter"])
 | 
			
		||||
    [aria-label="Timeline: Trending now"] {
 | 
			
		||||
    display: none !important;
 | 
			
		||||
  }
 | 
			
		||||
	[data-testid^="sidebarColumn"] {
 | 
			
		||||
		display: none;
 | 
			
		||||
	}
 | 
			
		||||
  `
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (document.domain == "reddit.com" || document.domain == "old.reddit.com"){
 | 
			
		||||
	styles = `
 | 
			
		||||
	/* kill sidebar ads */
 | 
			
		||||
	.native-ad-container,
 | 
			
		||||
	.premium-banner-outer,
 | 
			
		||||
	.native-sidebar-ad,
 | 
			
		||||
	.infobar-toaster-container,
 | 
			
		||||
	#eu-cookie-policy,
 | 
			
		||||
	.ad-container,
 | 
			
		||||
	.listingsignupbar,
 | 
			
		||||
	a[href="/premium"],
 | 
			
		||||
	[data-promoted^="true"],
 | 
			
		||||
	a[href^="https://alb.reddit.com"]
 | 
			
		||||
	{
 | 
			
		||||
		display: none !important;
 | 
			
		||||
	}
 | 
			
		||||
	`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,4 +107,64 @@ if(styles != null){
 | 
			
		|||
	  console.log('Style changed')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Replace default alert with new function
 | 
			
		||||
// whose style can be changed!
 | 
			
		||||
window.alert = (message) => {
 | 
			
		||||
    let alertDiv = document.getElementById('customAlert');
 | 
			
		||||
    if (!alertDiv) {
 | 
			
		||||
        const html = `
 | 
			
		||||
            <div id="customAlert" class="custom-alert">
 | 
			
		||||
                <div class="custom-alert-content">
 | 
			
		||||
                    <p id="alertMessage"></p>
 | 
			
		||||
                    <button id="alertOkButton">OK</button>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <style>
 | 
			
		||||
                .custom-alert {
 | 
			
		||||
                    display: none;
 | 
			
		||||
                    position: fixed;
 | 
			
		||||
                    z-index: 999;
 | 
			
		||||
                    left: 0;
 | 
			
		||||
                    top: 0;
 | 
			
		||||
                    width: 100%;
 | 
			
		||||
                    height: 100%;
 | 
			
		||||
                    overflow: auto;
 | 
			
		||||
                    background-color: rgba(0,0,0,0.4);
 | 
			
		||||
                }
 | 
			
		||||
                .custom-alert-content {
 | 
			
		||||
                    background-color: #fefefe;
 | 
			
		||||
                    margin: 15% auto;
 | 
			
		||||
                    padding: 20px;
 | 
			
		||||
                    border: 1px solid #888;
 | 
			
		||||
                    width: 80%;
 | 
			
		||||
                    font-family: monospace; /* Use monospace font */
 | 
			
		||||
                }
 | 
			
		||||
                .visible {
 | 
			
		||||
                    display: block;
 | 
			
		||||
                }
 | 
			
		||||
            </style>
 | 
			
		||||
        `;
 | 
			
		||||
        document.body.insertAdjacentHTML('beforeend', html);
 | 
			
		||||
        alertDiv = document.getElementById('customAlert');
 | 
			
		||||
        document.getElementById('alertOkButton').onclick = () => {
 | 
			
		||||
            alertDiv.classList.remove('visible');
 | 
			
		||||
            document.removeEventListener('keydown', dismissAlert);
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    const dismissAlert = (event) => {
 | 
			
		||||
        if (event.key === 'Enter' /*&& event.ctrlKey*/ && alertDiv.classList.contains('visible')) {
 | 
			
		||||
            alertDiv.classList.remove('visible');
 | 
			
		||||
            document.removeEventListener('keydown', dismissAlert);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    document.addEventListener('keydown', dismissAlert);
 | 
			
		||||
    document.getElementById('alertMessage').textContent = message;
 | 
			
		||||
    alertDiv.classList.add('visible');
 | 
			
		||||
}
 | 
			
		||||
// ^ takes 0.014ms to run, so performance is not the concern here.
 | 
			
		||||
// timed with console.time, console.timeEnd
 | 
			
		||||
 | 
			
		||||
document.body.style.visibility = "visible"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										90
									
								
								rose.c
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								rose.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
 | 
			
		||||
#include "plugins/libre_redirect/libre_redirect.h"
 | 
			
		||||
#include "plugins/readability/readability.h"
 | 
			
		||||
#include "plugins/shortcuts/shortcuts.h"
 | 
			
		||||
#include "plugins/style/style.h"
 | 
			
		||||
 | 
			
		||||
// #include "plugins/stand_in/stand_in.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +15,8 @@
 | 
			
		|||
int LIBRE_REDIRECT_ENABLED = true;
 | 
			
		||||
int READABILITY_ENABLED = true;
 | 
			
		||||
int CUSTOM_STYLE_ENABLED = true;
 | 
			
		||||
int CUSTOM_USER_AGENT = true;
 | 
			
		||||
int CUSTOM_USER_AGENT = false;
 | 
			
		||||
int NUM_TABS = 0;
 | 
			
		||||
 | 
			
		||||
// to enable plugins,
 | 
			
		||||
// 1. Enable them:
 | 
			
		||||
| 
						 | 
				
			
			@ -96,10 +98,19 @@ void load_uri(WebKitWebView* view, const char* uri)
 | 
			
		|||
    if (g_str_has_prefix(uri, "http://") || g_str_has_prefix(uri, "https://") || g_str_has_prefix(uri, "file://") || g_str_has_prefix(uri, "about:")) {
 | 
			
		||||
        webkit_web_view_load_uri(view, uri);
 | 
			
		||||
    } else {
 | 
			
		||||
        // webkit_web_view_load_uri(view, uri);
 | 
			
		||||
        char tmp[strlen(uri) + strlen(SEARCH)];
 | 
			
		||||
        snprintf(tmp, sizeof(tmp), SEARCH, uri);
 | 
			
		||||
        webkit_web_view_load_uri(view, tmp);
 | 
			
		||||
        // Check for shortcuts
 | 
			
		||||
        int l = SHORTCUT_N + strlen(uri) + 1;
 | 
			
		||||
        char uri_expanded[l];
 | 
			
		||||
        str_init(uri_expanded, l);
 | 
			
		||||
        int check = shortcut_expand(uri, uri_expanded);
 | 
			
		||||
        if (check == 2) {
 | 
			
		||||
            webkit_web_view_load_uri(view, uri_expanded);
 | 
			
		||||
        } else {
 | 
			
		||||
            // Feed into search engine.
 | 
			
		||||
            char tmp[strlen(uri) + strlen(SEARCH)];
 | 
			
		||||
            snprintf(tmp, sizeof(tmp), SEARCH, uri);
 | 
			
		||||
            webkit_web_view_load_uri(view, tmp);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -183,12 +194,17 @@ GtkWidget* handle_create_new_tab(WebKitWebView* self,
 | 
			
		|||
    WebKitNavigationAction* navigation_action,
 | 
			
		||||
    GtkNotebook* notebook)
 | 
			
		||||
{
 | 
			
		||||
    WebKitURIRequest* uri_request = webkit_navigation_action_get_request(navigation_action);
 | 
			
		||||
    const char* uri = webkit_uri_request_get_uri(uri_request);
 | 
			
		||||
    printf("Creating new window: %s\n", uri);
 | 
			
		||||
    notebook_append(notebook, uri);
 | 
			
		||||
    gtk_notebook_set_show_tabs(notebook, true);
 | 
			
		||||
    return NULL;
 | 
			
		||||
    if (NUM_TABS < MAX_NUM_TABS || NUM_TABS == 0) {
 | 
			
		||||
        WebKitURIRequest* uri_request = webkit_navigation_action_get_request(navigation_action);
 | 
			
		||||
        const char* uri = webkit_uri_request_get_uri(uri_request);
 | 
			
		||||
        printf("Creating new window: %s\n", uri);
 | 
			
		||||
        notebook_append(notebook, uri);
 | 
			
		||||
        gtk_notebook_set_show_tabs(notebook, true);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    } else {
 | 
			
		||||
        webkit_web_view_run_javascript(notebook_get_webview(notebook),
 | 
			
		||||
            "alert('Too many tabs, not opening a new one')", NULL, NULL, NULL);
 | 
			
		||||
    }
 | 
			
		||||
    /* WebKitGTK documentation recommends returning the new webview.
 | 
			
		||||
   * I imagine that this might allow e.g., to go back in a new tab
 | 
			
		||||
   * or generally to keep track of history.
 | 
			
		||||
| 
						 | 
				
			
			@ -199,27 +215,42 @@ GtkWidget* handle_create_new_tab(WebKitWebView* self,
 | 
			
		|||
 | 
			
		||||
void notebook_append(GtkNotebook* notebook, const char* uri)
 | 
			
		||||
{
 | 
			
		||||
    GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(window));
 | 
			
		||||
    GdkVisual* rgba_visual = gdk_screen_get_rgba_visual(screen);
 | 
			
		||||
    GdkRGBA rgba;
 | 
			
		||||
    if (NUM_TABS < MAX_NUM_TABS || NUM_TABS == 0) {
 | 
			
		||||
        GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(window));
 | 
			
		||||
        GdkVisual* rgba_visual = gdk_screen_get_rgba_visual(screen);
 | 
			
		||||
        GdkRGBA rgba;
 | 
			
		||||
 | 
			
		||||
    gdk_rgba_parse(&rgba, BG_COLOR);
 | 
			
		||||
        gdk_rgba_parse(&rgba, BG_COLOR);
 | 
			
		||||
 | 
			
		||||
    WebKitWebView* view = webview_new();
 | 
			
		||||
        WebKitWebView* view = webview_new();
 | 
			
		||||
 | 
			
		||||
    gtk_widget_set_visual(GTK_WIDGET(window), rgba_visual);
 | 
			
		||||
    g_signal_connect(view, "load_changed", G_CALLBACK(load_changed), notebook);
 | 
			
		||||
    g_signal_connect(view, "create", G_CALLBACK(handle_create_new_tab), notebook);
 | 
			
		||||
        gtk_widget_set_visual(GTK_WIDGET(window), rgba_visual);
 | 
			
		||||
        g_signal_connect(view, "load_changed", G_CALLBACK(load_changed), notebook);
 | 
			
		||||
        g_signal_connect(view, "create", G_CALLBACK(handle_create_new_tab), notebook);
 | 
			
		||||
 | 
			
		||||
    int n = gtk_notebook_append_page(notebook, GTK_WIDGET(view), NULL);
 | 
			
		||||
    gtk_notebook_set_tab_reorderable(notebook, GTK_WIDGET(view), true);
 | 
			
		||||
    gtk_widget_show_all(GTK_WIDGET(window));
 | 
			
		||||
    gtk_widget_hide(GTK_WIDGET(bar));
 | 
			
		||||
    webkit_web_view_set_background_color(view, &rgba);
 | 
			
		||||
    load_uri(view, (uri) ? uri : HOME);
 | 
			
		||||
    gtk_notebook_set_current_page(notebook, n);
 | 
			
		||||
    gtk_notebook_set_tab_label_text(notebook, GTK_WIDGET(view), "-");
 | 
			
		||||
    webkit_web_view_set_zoom_level(view, ZOOM);
 | 
			
		||||
        int n = gtk_notebook_append_page(notebook, GTK_WIDGET(view), NULL);
 | 
			
		||||
        gtk_notebook_set_tab_reorderable(notebook, GTK_WIDGET(view), true);
 | 
			
		||||
        gtk_widget_show_all(GTK_WIDGET(window));
 | 
			
		||||
        gtk_widget_hide(GTK_WIDGET(bar));
 | 
			
		||||
        webkit_web_view_set_background_color(view, &rgba);
 | 
			
		||||
        load_uri(view, (uri) ? uri : HOME);
 | 
			
		||||
 | 
			
		||||
        if (CUSTOM_STYLE_ENABLED) {
 | 
			
		||||
            char* style_js = malloc(STYLE_N + 1);
 | 
			
		||||
            read_style_js(style_js);
 | 
			
		||||
            webkit_web_view_run_javascript(notebook_get_webview(notebook), style_js,
 | 
			
		||||
                NULL, NULL, NULL);
 | 
			
		||||
            free(style_js);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        gtk_notebook_set_current_page(notebook, n);
 | 
			
		||||
        gtk_notebook_set_tab_label_text(notebook, GTK_WIDGET(view), "-");
 | 
			
		||||
        webkit_web_view_set_zoom_level(view, ZOOM);
 | 
			
		||||
        NUM_TABS += 1;
 | 
			
		||||
    } else {
 | 
			
		||||
        webkit_web_view_run_javascript(notebook_get_webview(notebook),
 | 
			
		||||
            "alert('Too many tabs, not opening a new one')", NULL, NULL, NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void show_bar(GtkNotebook* notebook)
 | 
			
		||||
| 
						 | 
				
			
			@ -306,6 +337,7 @@ int handle_key(func id, GtkNotebook* notebook)
 | 
			
		|||
 | 
			
		||||
    case close_tab:
 | 
			
		||||
        gtk_notebook_remove_page(notebook, gtk_notebook_get_current_page(notebook));
 | 
			
		||||
        NUM_TABS -= 1;
 | 
			
		||||
 | 
			
		||||
        switch (gtk_notebook_get_n_pages(notebook)) {
 | 
			
		||||
        case 0:
 | 
			
		||||
| 
						 | 
				
			
			@ -436,7 +468,7 @@ void setup(GtkNotebook* notebook, int argc, char** argv)
 | 
			
		|||
    window_init(notebook);
 | 
			
		||||
 | 
			
		||||
    // Initialize with first uri
 | 
			
		||||
    char* first_uri = argc > 1 ? argv[1] : NULL;
 | 
			
		||||
    char* first_uri = argc > 1 ? argv[1] : HOME;
 | 
			
		||||
    notebook_init(notebook, first_uri);
 | 
			
		||||
    g_object_set(gtk_settings_get_default(), GTK, NULL);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										
											BIN
										
									
								
								screenshots/6-hello-world.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								screenshots/6-hello-world.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 302 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								screenshots/7-hello-world-search.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								screenshots/7-hello-world-search.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 42 KiB  | 
							
								
								
									
										20
									
								
								style.css
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								style.css
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -11,7 +11,7 @@
 | 
			
		|||
	outline-color: @Lavender;
 | 
			
		||||
	color: @Text;
 | 
			
		||||
	border-color: white;
 | 
			
		||||
	font-size: 16px;
 | 
			
		||||
	font-size: 25px;
 | 
			
		||||
	/*@Base; */
 | 
			
		||||
	/* border-bottom-color: @Base; */
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +20,23 @@ window, notebook, headerbar {
 | 
			
		|||
	background: @Base;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Make titlebar pretty gigantic. I'm pretty myopic. */
 | 
			
		||||
.titlebar  {
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  font-size: 30px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.titlebar * {
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  font-size: 27px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
header * {
 | 
			
		||||
  font-size: 20px;
 | 
			
		||||
  padding: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tabs {
 | 
			
		||||
	background-color: @Base;
 | 
			
		||||
	padding: 3px;
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +49,7 @@ tab {
 | 
			
		|||
	margin: 2px 5px 2px 0px;
 | 
			
		||||
	padding: 5px;
 | 
			
		||||
	border-style: solid;
 | 
			
		||||
  font-size: 27px;
 | 
			
		||||
	/*border-color: white;
 | 
			
		||||
	border-bottom-color: white;
 | 
			
		||||
	outline-color: white;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										9
									
								
								user-scripts/ubuntu-20.04/rose-GIO_MODULE_DIR.desktop
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										9
									
								
								user-scripts/ubuntu-20.04/rose-GIO_MODULE_DIR.desktop
									
									
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
#!/usr/bin/env xdg-open
 | 
			
		||||
[Desktop Entry]
 | 
			
		||||
Version=1.0
 | 
			
		||||
Type=Application
 | 
			
		||||
Terminal=false
 | 
			
		||||
Exec=/home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose.sh %u
 | 
			
		||||
Name=Rose
 | 
			
		||||
Comment=Minimalistic browser
 | 
			
		||||
Icon=/home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose-images/rose-desktop-icon.png
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								user-scripts/ubuntu-20.04/rose-images/rose-homepage-1.6-zoom.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								user-scripts/ubuntu-20.04/rose-images/rose-homepage-1.6-zoom.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 102 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								user-scripts/ubuntu-20.04/rose-images/rose-homepage-2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								user-scripts/ubuntu-20.04/rose-images/rose-homepage-2.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 142 KiB  | 
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
Version=1.0
 | 
			
		||||
Type=Application
 | 
			
		||||
Terminal=false
 | 
			
		||||
Exec= /usr/bin/rose %u
 | 
			
		||||
Exec=/bin/rose %u
 | 
			
		||||
Name=Rose
 | 
			
		||||
Comment=Minimalistic browser
 | 
			
		||||
Icon=/home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose-images/rose-desktop-icon.png
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										3
									
								
								user-scripts/ubuntu-20.04/rose.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										3
									
								
								user-scripts/ubuntu-20.04/rose.sh
									
									
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/ /bin/rose "$1"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user